0

I've tried to read the relavent sections of standard (secs 6.5 and 6.8 of c99), but this lead me to be more confused and without a clear answer. This is the code in question:

#include <stdio.h>
#include <time.h>

int t;
#define block {\
    int temp = 1; \
    t = time(NULL); \
    if (t == (time_t) -1 && temp) puts("turbulance ahead!");\
}

int main(){
    if (((block), t%2)) {
        puts("nice 'n even");
    }
    else {
        puts("odd..");
    }
    return 0;
}

Is the code valid c99/c1x? It compiles on clang and gcc without producing any errors, even when -Wall and -Wextra are set.

Sam Parker
  • 31
  • 3
  • 3
    this is the type of code i would not like to see - even if it compiles ^_^ – AndersK Feb 14 '14 at 11:25
  • OT: For the sake of readabilty follow the convention to use capitals for `#define`s: `#define BLOCK ...` but `#define block ...` – alk Feb 14 '14 at 11:32
  • Combining the `({` and `})` of statement expressions in this way is really bad style. Gcc people should at least have created special tokens that inhibit such a thing. – Jens Gustedt Feb 14 '14 at 12:17
  • @claptrap Me nether. I wrote it this way to better illustrate my question. – Sam Parker Feb 14 '14 at 19:32

3 Answers3

4

No. It's not valid under Standard C (C99/C11).

It's valid in GNU C, an extension as called statement expressions.

P.P
  • 117,907
  • 20
  • 175
  • 238
  • If it's not any trouble, could you point me to the relavent sections in the standard? – Sam Parker Feb 14 '14 at 19:28
  • @SamParker Standard only talks about what's *defined* by it, not what's *not* there. If you want to see some sort of proof then you can look at [here](http://gcc.gnu.org/onlinedocs/gcc-3.1.1/gcc/C-Extensions.html#C%20Extensions) where it says: `GNU C provides several language features not found in ISO standard C. (The -pedantic option directs GCC to print a warning message if any of these features is used.) To test for the availability of these features in conditional compilation, check for a predefined macro __GNUC__, which is always defined under GCC.` – P.P Feb 14 '14 at 19:56
  • If you want to check if there are are GCC extensions then compiling with: `gcc -std=c99 -pedantic -Wall -Wextra file.c` would give warnings about most (unfortunately not all) extensions. You can also look the list of [extensions provided by gcc](http://gcc.gnu.org/onlinedocs/gcc-3.1.1/gcc/C-Extensions.html#C%20Extensions) to familiarize yourself. – P.P Feb 14 '14 at 19:58
  • It's a bit disheartening that extensions aren't turned off with std. I'll try digging into gcc's documentation to investigate this further. Thank you for the detailed response. It's much appreciated. – Sam Parker Feb 15 '14 at 16:56
2
if (((block), t%2))

This evaluates to a statement expression followed by a comma operator. The return value of a block expression is the value of the last statement in the block. Comma operator evaluates from left to right and its value is equal to the last expression. If you try the -E option in gcc, you will get the preprocessed code, which looks like this:

if ((({ int temp = 1; t = time(((void *)0)); if (t == (time_t) -1 && temp) puts("turbulance ahead!");}), t%2)) 

So the condition in if statement is solely determined by the value of t%2(as per comma operator).

Is the code valid c99/c1x?

No. C99 generates warning for statement expressions.

Soumen
  • 1,068
  • 1
  • 12
  • 18
1

It compiles on clang and gcc

No it doesn't. Compile it as the C language, not as the "GNU goo" language.

gcc file.c -std=c99 -pedantic-errors -Wall -Wextra
Lundin
  • 195,001
  • 40
  • 254
  • 396
  • I compiled it with -std=c99 -Wall -Wextra, and no error messages were produced. I assumed that -std would turn off all extensions. I admit that I didn't include -pedantic-errors – Sam Parker Feb 14 '14 at 19:30