1

Why does this C code compile in C99? What should I read to learn more?

I can't post unless I add more text so here's some nonsense text because I don't think there's anything else to say

$ cat m.c
#include <stdio.h>
#include <time.h>
int main() {
    struct timespec time;
    int res = clock_gettime(CLOCK_REALTIME, &time);
    printf("%d %ld %ld\n", res, time.tv_sec, time.tv_nsec);
    return 0;
}


$ clang m.c && ./a.out && rm ./a.out
0 1631386905 774654955


$ clang -std=c99 m.c && ./a.out && rm ./a.out
m.c:4:18: error: variable has incomplete type 'struct timespec'
        struct timespec time;
                        ^
m.c:4:9: note: forward declaration of 'struct timespec'
        struct timespec time;
            ^
m.c:5:12: warning: implicit declaration of function 'clock_gettime' is invalid in C99 [-Wimplicit-function-declaration]
        int res = clock_gettime(CLOCK_REALTIME, &time);
                ^
m.c:5:26: error: use of undeclared identifier 'CLOCK_REALTIME'
        int res = clock_gettime(CLOCK_REALTIME, &time);
                                ^
1 warning and 2 errors generated.
3
  • does this answer? stackoverflow.com/questions/3875197/… c11 has it, and some other stuff (posix) has it. just c99 does not. enable that other stuff if using c99 Commented Sep 14, 2021 at 0:31
  • 2
    clock_gettime is not a part of C99, the code could be compiled either with the GNU99 extension -std=gnu99, or with the #define _POSIX_C_SOURCE 200112L macro Commented Sep 14, 2021 at 0:35
  • The "invalid in C99" is because without the POSIX feature test macros enabled, <time.h> doesn't contain a declaration of clock_gettime. Prior to C99 it was legal (though usually wrong) to use a function even if hadn't been declared; the compiler assumed an implicit declaration of the function as returning int and taking unspecified arguments. In C99 this was made undefined behavior, but GCC will still provide the older behavior after giving a warning. Anyway, you don't want any of that; the right fix is to define the feature test macro and get the proper declaration from <time.h>. Commented Sep 14, 2021 at 0:43

1 Answer 1

5
+100

It’s because using the -std=c99 option defines a macro that causes the declaration of clock_gettime to be hidden.

The GNU C library can expose different versions of its functions, or hide them altogether, depending on what is expected by user code. User code declares those expectations by defining certain specially-named macros (called feature test macros, though this is something of a misnomer) with pre-determined values recognised by the GNU C library headers. One such macro is __STRICT_ANSI__, which is implicitly defined if any of the -std=cXX options are used.

Quoting feature_test_macros(7):

__STRICT_ANSI__

ISO Standard C. This macro is implicitly defined by gcc(1) when invoked with, for example, the -std=c99 or -ansi flag.

[…]

If any of __STRICT_ANSI__, _ISOC99_SOURCE, _ISOC11_SOURCE (since glibc 2.18), _POSIX_SOURCE, _POSIX_C_SOURCE, _XOPEN_SOURCE, _XOPEN_SOURCE_EXTENDED (in glibc 2.11 and earlier), _BSD_SOURCE (in glibc 2.19 and earlier), or _SVID_SOURCE (in glibc 2.19 and earlier) is explicitly defined, then _BSD_SOURCE, _SVID_SOURCE, and _DEFAULT_SOURCE are not defined by default.

Using -std=gnuXX option instead of -std=cXX does not cause __STRICT_ANSI__ to be defined; it also enables GNU extensions to the C language. If you want to keep those language extensions disabled, you can instead put #define _DEFAULT_SOURCE 1 at the very top of the file to expose all the symbols the C library otherwise would expose (or perhaps another feature test macro to adjust the library interface to your liking). An explicit feature test macro will take precedence over __STRICT_ANSI__.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.