Question

I wanted to use getopt, but it just won't work.

It's giving me

gcc -g -Wall -std=c99 -ftrapv -O2 -Werror -Wshadow -Wundef -save-temps -Werror-implicit-function-declaration   -c -o src/main.o src/main.c
src/main.c: In function ‘main’:
src/main.c:13:2: error: implicit declaration of function ‘getopt’ [-Werror=implicit-function-declaration]
src/main.c:23:14: error: ‘optarg’ undeclared (first use in this function)
src/main.c:23:14: note: each undeclared identifier is reported only once for each function it appears in
src/main.c:26:9: error: ‘optopt’ undeclared (first use in this function)
src/main.c:28:5: error: implicit declaration of function ‘isprint’ [-Werror=implicit-function-declaration]
src/main.c:36:5: error: implicit declaration of function ‘abort’ [-Werror=implicit-function-declaration]
src/main.c:36:5: error: incompatible implicit declaration of built-in function ‘abort’ [-Werror]
src/main.c:43:15: error: ‘optind’ undeclared (first use in this function)
cc1: all warnings being treated as errors
make: *** [src/main.o] Error 1

Here's the source if you wanna see it (almost exact copypasta from getopt manpage)

#include <stdio.h>
#include <unistd.h> // getopt
#include "myfn.h"

int main(int argc, char *argv[])
{

    int aflag = 0;
    int bflag = 0;
    char *cvalue = NULL;
    int c;

    while((c = getopt(argc, argv, "abc:")) != -1) {

        switch(c) {
            case 'a':
                aflag = 1;
                break;
            case 'b':
                bflag = 1;
                break;
            case 'c':
                cvalue = optarg;
                break;
            case '?':
                if (optopt == 'c')
                    fprintf (stderr, "Option -%c requires an argument.\n", optopt);
                else if (isprint(optopt))
                    fprintf (stderr, "Unknown option `-%c'.\n", optopt);
                else
                    fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt);

                return 1;

            default:
                abort ();
        }

    }

    printf ("aflag = %d, bflag = %d, cvalue = %s\n", aflag, bflag, cvalue);

    for (int i = optind; i < argc; i++) {
        printf ("Non-option argument %s\n", argv[i]);
    }

    return 0;
}

Any ideas what I'm doing wrong?

I'm on Linux, so I assumed it should work like this.

Was it helpful?

Solution

Try removing the -std=c99. This disables the GNU extensions and thus prevents the POSIX macros from being defined in <features.h>, which prevents <unistd.h> from including <getopt.h>.
Or replace the flag by -std=gnu99.
Or include getopt.h yourself.

It is a GNU extension that getopt() is part of unistd.h. By setting -std=c99 no GNU extensions are used, the function is no longer declared and you need to explicitly include getopt.h.

OTHER TIPS

You cloud not remove -std=c99. Instead, add #define _POSIX_C_SOURCE 2 at beginning.

Add #include <getopt.h> among the includes.

There is absolute no need to change the -std or to include getopt.h directly.

The right thing to do if you want to use the C99 (or any other standardized) language features together with POSIX functions (like getopt) is to define _POSIX_C_SOURCE to the right version (e.g., 200809L) before including the respective headers. For more details see feature_test_macros(7).

I had the same issue, the way to fix it is you're most likely compiling with -std=c99, but instead try -std=gnu99 and it should work.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top