Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clang fails to compile a c11 program, citing that "implicit declaration is illegal in c99"

Tags:

c

posix

clang

I have written this trivial little program to demonstrate my problem (titled hello.c) (sidenote: I have noticed the memory leak in this program but it's just an example so it's not important):

#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char ** argv) {
    char * buf = NULL;
    size_t buflen = 0;

    ssize_t line_len;

    while ((line_len = getline(&buf, &buflen, stdin)) > 0) {
        buf[line_len - 1] = '\0';

        char * val = getenv(buf);

        if (val) {
            printf("setenv %s \"%s\"\n", buf, val);
        }
        else {
            fprintf(stderr, "warning: %s not found\n", buf);
        }
    }

    return EXIT_SUCCESS;
}

This compiles fine under Linux, using gcc and gnu make with the following makefile:

CFLAGS += -std=c11 -Wall -Werror -Wpedantic
CPPFLAGS := -D_XOPEN_SOURCE=700

EXES := hello

all: $(EXES)

clean:
    rm -f $(EXES) *.o

However, under BSD, using clang and bmake, I cannot compile (using the exact same makefile and source file), because it says

hello.c:11:24: error: implicit declaration of function 'getline' is invalid in
  C99 [-Werror,-Wimplicit-function-declaration]

The trouble is, as you can see, that I'm not compiling in c99 mode, but c11, and also, according to the man page defining _POSIX_C_SOURCE to be 200809 or greater should enable getline, and elsewhere I am assured that defining _XOPEN_SOURCE to be 700 should achieve that.

Taking out the -W flags doesn't help.

So, what am I doing wrong? How can I get this to compile? I'm stumped.

like image 881
scott_fakename Avatar asked Jan 24 '15 05:01

scott_fakename


1 Answers

You have set -std=c11 -Wpedantic, which means that the normal defines are not available and POSIX function are not declared unless you explicitly set one of _POSIX_C_SOURCE or _XOPEN_SOURCE. Add #define _XOPEN_SOURCE 700 (or even 800 on Linux) before the first #include and all will be well.

You have CPPFLAGS = -D_XOPEN_SOURCE=700 in the makefile; does CPPFLAGS actually show on the GCC command line?

I routinely compile on Mac OS X 10.10.1 with -std=c11 and I have a header which sets _XOPEN_SOURCE to 700. However, I can take your code and compile it verbatim with:

gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \
    -Wold-style-definition -Werror -pedantic -c yourprog.c

and the only complaint is that neither argc nor argv is used (so the compilation does fail, but not because of getline()).

Note that CPPFLAGS is not necessarily recognized by BSD make. There isn't a universal standard that requires CPPFLAGS to be recognized.

like image 163
Jonathan Leffler Avatar answered Oct 22 '22 05:10

Jonathan Leffler