?
Solved

stdint and __attribute__(format)

Posted on 2012-04-04
9
Medium Priority
?
856 Views
Last Modified: 2012-06-21
I'm using a custom function to supplement printf based on a debug level that is defined in the source.  (see code below).  When I turned on the warning -Wmissing-format-attribute in gcc it flagged the function with:
warning: function might be possible candidate for 'printf' format attribute

With a little reading I found a solution to be adding __attribute__(format)  to the declaration so the compiler checks that calls to the function meet the formatting rules of printf.  More precisely the declaration is now:

extern int32_t printfl(const uint8_t print_level, const char *print_me, ...)__attribute__((format(printf, 2, 3)));

That worked, but now for all the calls to the function I'm getting a warning about argument types that don't match. For example:
warning: format '%i' expects type 'int', but argument 3 has type 'int32_t'

Of course int and int32_t are the same thing and I'm certain stdint.h is include in all these locations.

How can I get the __attribute__(format) capability to use the stdint types?

Thanks.


/* Specialized printf function that allows for printing of messages
 * based on a global print level.
 */
int32_t printfl(const uint8_t print_level, const char *print_me, ...)
{
	va_list ap;
	int32_t ret = 0;

	if ( g_comm_config.print_level == 0){
		return 0;
	}

	if ( print_level <= g_comm_config.print_level  )
	{
		va_start(ap, print_me);
		ret = vfprintf(stdout, print_me, ap);
		va_end(ap);
		fflush(stdout);
	}

	return ret;
}

Open in new window

0
Comment
Question by:JohnSantaFe
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 4
9 Comments
 
LVL 53

Expert Comment

by:Infinity08
ID: 37809811
>> How can I get the __attribute__(format) capability to use the stdint types?

It does for me.

What version of gcc are you using ?
What compiler flags are you passing ?
Can you post a minimal compilable sample that has the behavior you see ?
0
 

Author Comment

by:JohnSantaFe
ID: 37812317
I'm using gcc version 4.3.3.  It's a version for the sparc architecture with the RTEMS operating: system:  sparc-rtems-gcc

Leaving out all the -W warning flags here's what the compile line looks like for the first object:
sparc-rtems-gcc -O0 -mcpu=v8 -g -I./include/  <snip -W's> -c -o bin/CH_Manager.o src/CH_Manager.c

The application includes the RTEMS operating system code so trying to post a full example would be hard.

Is __attribute__ a flag for the compiler and thus this is a gcc issue, or does that come from some library?

Thanks.
0
 
LVL 86

Expert Comment

by:jkr
ID: 37812989
'__attribute__' is absolutely gcc-specific, not part of a standard.
0
Get 15 Days FREE Full-Featured Trial

Benefit from a mission critical IT monitoring with Monitis Premium or get it FREE for your entry level monitoring needs.
-Over 200,000 users
-More than 300,000 websites monitored
-Used in 197 countries
-Recommended by 98% of users

 
LVL 53

Expert Comment

by:Infinity08
ID: 37828713
Sorry for the delay.

>> Leaving out all the -W warning flags

I was actually wanting to see the warning flags specifically, since what you observe is a warning message that you didn't expect.

The cross-compilation bit might be part of the equation though. Are you sure that for the target architecture, int and int32_t are the same ?
0
 

Author Comment

by:JohnSantaFe
ID: 37834414
Also, sorry for the delay.

Here is the entire compiler line:
make all
sparc-rtems-gcc -O0 -mcpu=v8 -g -I./include/ -Wall -Wsign-compare -Waggregate-return -Wbad-function-cast -Wcast-align -Wfloat-equal -Wformat-nonliteral -Winline -Wmissing-declarations -Wmissing-format-attribute -Wmissing-prototypes -Wnested-externs -Wno-deprecated-declarations -Wno-format-y2k -Wpacked -Wpointer-arith -Wredundant-decls -Wshadow -Wstrict-prototypes  -Wundef -Wunreachable-code  -c -o bin/CH_Manager.o src/CH_Manager.c

I'm absolutely certain that the system is 32 bit and should be treating int and int32_t.  

However, I did find another strange clue.  The warning is only being generated when  the variable is a uint32_t or int32_t
e.g.
warning: format '%i' expects type 'int', but argument 3 has type 'int32_t'
or
warning: format '%08x' expects type 'unsigned int', but argument 3 has type 'uint32_t'

When the variable is a uint8_t or a uint16_t the warning is not generated.....hmmm
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 37834541
>> When the variable is a uint8_t or a uint16_t the warning is not generated.....hmmm

That further points in the direction that int32_t has a larger width than int.

The warning indicates that not all possible values of an int32_t can be held by an int.

It is always possible that the warning was generated in error.

But for my peace of mind, could you double-check what int32_t is defined as for the target platform ?
Could you also check whether it might not have been re-defined to something other than int by accident ?
0
 

Author Comment

by:JohnSantaFe
ID: 37835051
So I right click in int32_t and go to its declaration, it takes me to stdint.h.  Here's the typdefs:
/* 7.18.1.1  Exact-width integer types */
typedef signed char int8_t;
typedef unsigned char   uint8_t;
typedef short  int16_t;
typedef unsigned short  uint16_t;
typedef int  int32_t;
typedef unsigned   uint32_t;
typedef long long  int64_t;
typedef unsigned long long   uint64_t;

Another piece of evidence is I definitely get the warning every time int32_t and uint32_t are used, and, I also get the error when two other types are used:

warning: format '%i' expects type 'int', but argument 3 has type 'mqd_t'
warning: format '%i' expects type 'int', but argument 3 has type 'socket_t'

mqd_t is a message queue descriptor that is typed in mqueue.h as a uint32_t and socket_t is typed as an int32_t in my own code.
0
 
LVL 53

Accepted Solution

by:
Infinity08 earned 1500 total points
ID: 37835233
>> So I right click in int32_t and go to its declaration, it takes me to stdint.h.  Here's the typdefs:

Ok. Then I guess gcc is wrong heh :)

To get rid of the warnings, you could do an explicit cast to int.
0
 

Author Closing Comment

by:JohnSantaFe
ID: 37943853
Looks like the compiler isn't wanting to cooperate.  Thanks for the help.
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

If you’re thinking to yourself “That description sounds a lot like two people doing the work that one could accomplish,” you’re not alone.
Today, the web development industry is booming, and many people consider it to be their vocation. The question you may be asking yourself is – how do I become a web developer?
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
With the power of JIRA, there's an unlimited number of ways you can customize it, use it and benefit from it. With that in mind, there's bound to be things that I wasn't able to cover in this course. With this summary we'll look at some places to go…

752 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question