Page 1 of 1

C Comma notation

Posted: Thu Feb 05, 2004 3:18 pm
by Curufir
Just got back to writing some C and this one has me stuck.

I've been looking in a few header files at the methods other people are using for macros, in particular the stdarg.h file (Someone on the OS dev board mentioned it).

Anyway. The macro that's bugging me follows this format:

Code: Select all

#define a_macro(arg) (arg = (Some value), (void) 0)
And it gets used like:

Code: Select all

a_macro (arg);
The macro isn't the problem, I understand exactly what it's doing. The problem is I just don't get what the (void) 0 is doing there. As far as I know that's effectively a null operation, and my hazy memory tells me that , notation goes something like this:

Code: Select all

A = (( B = 20), 50);

Means:

A = 50;
B = 20;
This is where I get hazy. That, I think, would make the macro do something like:

Code: Select all

a_macro (arg);

Gets replaced with:

(arg = (Some value), (void) 0)

Which means:

arg1 = (Some value);
(void) 0;
I checked this by writing a little C code:

Code: Select all

   int i;
   (i=2, (void) 0);
   printf("%d", i);
Sure enough i is set to 2.

So I guess the question here is just what the heck that (void) 0 is achieving? It seems to serve no purpose whatsoever. I took a good long look around the web this afternoon and couldn't find anything explaining it. I know it isn't an isolated thing because I went digging around a whole bunch of header files after finding this and it is used all over the place. I'm guessing it's just such a widely followed practice, or is so obvious, that nobody has bothered writing down WHY it's done.

Any chance one of the C gurus could please give an explanation?

Re:C Comma notation

Posted: Thu Feb 05, 2004 3:50 pm
by Tim
It's useless here.

I think some pre-ANSI C compilers would complain if you used a non-void function but ignored the return value. For instance, you might have written (void) printf("hello, world\n");

What is the actual line of code you've seen it in?

Re:C Comma notation

Posted: Thu Feb 05, 2004 3:52 pm
by Curufir
So I went off and grabbed a bite to eat, came back and apparently my brain started working again.

Could it be that it's just a failsafe for debugging?

Code: Select all

int i, j

j = ( i = 2, (void) 0 );
Will kick up a nice compiler error on the correct line of the program. So could it just be there for debugging purposes in case someone tries to misuse the macro?

Re:C Comma notation

Posted: Thu Feb 05, 2004 3:53 pm
by Curufir
What is the actual line of code you've seen it in?

Code: Select all

#define va_start(ap, parm)  ((ap)[0] = (char *) &parm \
         + ((sizeof(parm) + sizeof(int) - 1) & ~(sizeof(int) - 1)), (void) 0)
That's from the novell implementation of stdarg.h

Re:C Comma notation

Posted: Thu Feb 05, 2004 4:37 pm
by Tim
Curufir wrote:Could it be that it's just a failsafe for debugging?
I think you're right -- I was about to say that too. You'd see the same error as if you'd tried to use the result of a void function.

Still, a comment would have been nice.

Re:C Comma notation

Posted: Thu Feb 05, 2004 5:54 pm
by Curufir
Well it was bugging me sufficiently that I did some more research. I think it's to provide compliance to the ISO C spec.

The C spec (The only ISO one I could find) says the standard form is this:

[pre]
void va_start(va_list ap, parmN);
[/pre]

So macro or real function I guess it has to return void to be compliant.

Fun adventure. At least now I know how to return values from macros ;D.

Re:C Comma notation

Posted: Fri Feb 06, 2004 3:47 am
by Solar
You're on the right track, Curufir.

The macro must assign a value to arg. The return value of an assignment is the assigned value. But the C standard, in several places, requires macros to be of void value, so hence the trickery with the comma operator (because the return value of statements seperated with comma is the value of the last statement).

Ugly, but it works. ;-)