简体   繁体   中英

Do I need -pedantic flag from GCC with C11?

I'm currently running Linux Mint on my Machine with GCC-5.3 because C11 is included default.

I started learning C for myself just for fun and at that time the GCC version was 4.8 if I remember right.

Any way if one use GCC-4.8 with -pedantic flag on the following program:

#include <stdio.h>
#include <string.h>

int main(void){
    char *arr = "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890";
    size_t length = strlen(arr);
    printf("Length of Arr = %zu\n",length);
}

At the compile time one gets the following warnings:

program.c: In function ‘main’:
program.c:5:5: warning: string length ‘510’ is greater than the length ‘509’ ISO C90 compilers are required to support [-Woverlength-strings]
     char *arr = "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890";
     ^
program.c:7:5: warning: ISO C90 does not support the ‘z’ gnu_printf length modifier [-Wformat=]
     printf("Length of Arr = %zu\n",length);
     ^
program.c:8:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^

If we see this part of the warning:

warning: string length ‘510’ is greater than the length ‘509’ ISO C90 compilers are required to support [-Woverlength-strings]

Is somehow clear that -pedantic flag is a problem here so I decided to not use it and avoid it like avoid -ansi too because of the new (last) standard C11 .

Now if I compile the same program with GCC-5.3 :

gcc-5 -Wall -pedantic program.c -o program

The program compiles fine with NO WARNINGS.

Now based on the following Question Return void type in C and C++ if I try to compile the following program:

#include <stdio.h>
#include <string.h>

void f(void);
void f2(void);

int main(void){
    f();
}


void f(void){
}

void f2(void){
    return f();
}

With the following:

gcc-5 -Wall -pedantic program.c -o program

I get:

program.c: In function ‘f2’:
program.c:16:16: warning: ISO C forbids ‘return’ with expression, in function returning void [-Wpedantic]
         return f();
                ^

But compiles fine without the ´-pedantic` flag. This is a confusion for me.

Which shows me that somehow I do need the -pedantic flag, but I'm not sore.

So, my Question is, do we need to make use of -pedantic anymore with C11 ?

If you need it, you need it. If you don't, you don't.

gcc's -pedantic option tells it to strictly enforce the rules of the C standard you've requested. This results in additional warning messages (or fatal errors if you use -pedantic-errors ).

The question is, do you want the compiler to warn you about code that violates the requirements of the C standard?

If you want your code to be as portable as possible, use -pedantic and pay close attention to anything it tells you. If you want your code to depend on non-standard features, don't use -pedantic -- but then you run the risk that your code might not compile with a different compiler and/or for a different target system.

The specific messages you're run into are for things that have changed between C90 and C11. C11 requires compilers to support at least 4095 characters in a string literal; C90 only requires 509. (In practice, for gcc, the actual limit is not fixed but is imposed by available memory at compile time. And the way the limits are described in the standard is not that simple, but I won't get into that.) Still, you'll rarely need to have a string literal that long.

C99 added the %zu format for printing a value of type size_t . If you want your code to be portable to pre-C99 implementations, you'll need to avoid using it; for example, you can use printf("%lu\\n", (unsigned long)sizeof foo) . In practice, most current implementations do support %zu .

A return statement with an expression, even an expression of type void , is not permitted in a function defined with a void return type. That's a warning you should want (IMHO).

Bottom line: Use -pedantic if you want to strictly enforce the rules of the C standard. If you don't want to do that, don't use -pedantic . (But consider compiling your code with -pedantic at least occasionally to weed out any real errors it detects, in addition to warnings that you might not care about.)

The original C C89/C90 standard only required the compiler to allow string literals up to 509 bytes long. Code compiled to C90 standard using a string longer than 509 bytes long is not maximally portable; a standard-conforming compiler could reject the code. It is unlikely to be a problem in practice, but in theory that could happen.

The limit was raised in C99 to 4095 bytes (and stayed the same in C11). Consequently, you have to have a much longer string to run foul of the limit with C99 or C11.

The GCC 4.x compilers worked with the C90 standard by default. The GCC 5.x compilers work with the C11 standard by default. Thus, code that is not maximally portable to C90 will generate warnings when compiled with -pedantic under GCC 4.x, but won't generate the same warnings with GCC 5.x unless the construct is also not portable to all C11 compilers — unless it violates one of the C11 compile-time limits too.

The -pedantic flag has its uses. For example, yesterday, someone was running into problems because they were using:

void *p = malloc(sizeof(*p));

That's malformed code according to the standard, but GCC (5.3.0 specifically tested, but the other 5.x and 4.x versions behave the same) allows it, interpreting sizeof(*p) as being 1 . That's not portable to other compilers. Using -pedantic reports the problem; not using -pedantic does not.

From the formal point of view, if you are planning to write your code in standard C you definitely need -pedantic flag (moreover, -pedantic-errors might be even better idea). However, the original implementation of -pedantic suffered from one rather questionable design decision: it included warnings related to implementation limits (which is OK), and on top of that it also turned them into errors in -pedantic-errors mode (which, in my opinion, is unacceptable).

Warnings about implementation limits might be useful, but still it might be a good idea to keep them controllable independently, keeping -pedantic reserved for straightforward constraint violations.

The fact that you no longer see warnings about implementation limits with -pedantic might mean that GCC 5 finally decided to take care of this matter. If so, it would be a welcome change (but more likely it is the limits that changed).

-pedantic is just a flag that turns on a whole bunch of warnings and errors and you can use it if you want, but it sounds like you really aren't using c11 or else it wouldn't give you that particular warning...

try:

gcc -std=c11 -Wall -pedantic program.c -o program

that will make pre gcc-5 version use the C11 std as default rather than gnu89

The default mode for C is now -std=gnu11 instead of -std=gnu89

from gcc.gnu.org/gcc-5/changes.html

and to go into a little more detail: the difference between c11 and gnu11 is subtle, I haven't looked into c11 as much, but in c99/gnu99 the relationship was the gnu99 was a superset of c11 and allowed some compiler extensions to the language... I highly suspect this is the same relationship with c11/gnu11

That [-Wpedantic] at the end of the error message means that the warning is generated by -pedantic compiler option. In other words -pedantic is already enabled.

You do not need the -pedantic flag. Almost nobody needs the -pedantic flag.

Pedantry - Excessive concern with minor details and rules.

-pedantic warnings can be ignored, practically by definition. The flag may be useful when writing cross-platform code but that's it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM