3

I'm using Clang v3.7.0 with Mingw-w64 5.1.0 and GCC 5.1.0, all 64-bit, on Windows 10. My goal is to use a set of Clang and GCC options that will give me the best chance of detecting potential C89 and C++98 language standards portability issues across many different compilers. For example, for C I have been using the following GCC command line with pretty good success:

gcc -c -x c -std=c89 -pedantic-errors -Wall -Wextra -Wno-comment -Wno-parentheses -Wno-format-zero-length test.c

However, I recently tried it with Clang and got a different result. Here is my sample test code:

int main(void)
{
    int length = (int)strlen("Hello");
    return 0;
}

With Clang I get the following error, whereas with GCC I get the same basic thing, but it flags it as a warning instead:

test.c:3:22: error: implicitly declaring library function 'strlen'
with type 'unsigned long long (const char *)'
    int length = (int)strlen("Hello");

If I remove the -pedantic-errors option, or just change it to -pedantic, Clang then only flags it as a warning, which is what I actually want. However, according to the GCC documentation the -pedantic-errors option causes warnings that are considered language extensions to be flagged as errors, but not using a prototype for a function is not an extension in C89. So, I have three basic questions:

  1. Has Clang changed the meaning of -pedantic-errors from the meaning used by GCC, or am I misinterpreting something?

  2. What is the best set of options that will enforce adherence to the selected standard and will issue errors for all non-conforming code?

  3. If I continue to use -pedantic-errors with Clang is there a way to get it to issue a warning instead of an error in specific cases? In another posting on this site an answer was given that said to use the following, where foo is the error:

    -Wno-error=foo
    

If that is a correct approach, what do I actually use in place of foo for an error like I'm getting since there is no actual error number indicated? I can't believe it actually wants all of the following:

-Wno-error=implicitly declaring library function 'strlen'
with type 'unsigned long long (const char *)'
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
BenevolentDeity
  • 587
  • 6
  • 15
  • What do you meant with "standard"? There is exactly one C standard which is ISO9899:2011, aka C11. The other are not standard, but outdated **previous** versions. The rest of your question is not clearer. For the **required** warnings see the standard, otherwise see the documentation of gcc and clang. Last time I check something, they were well documented and freely available online (resp. in your prefered Linux installation). If you knew that already: Feel free to share what you found out by your own research. We might avoid writing what you already know. – too honest for this site Aug 08 '16 at 02:44
  • 2
    Oh, and you really should not use C89. It is outdated since 17 years now and not fully compatible with standard C. Similar for C++98. C++11 has changed a lot to the better. – too honest for this site Aug 08 '16 at 02:48
  • 3
    @Olaf: Earlier editions of the C standard did not magically vanish when later editions were published. They still exist, and gcc still supports them. Note that the current C++ standard still refers, in normative text, to the C99 standard, which you claim doesn't exist. I believe the same is true of POSIX. – Keith Thompson Aug 08 '16 at 02:59
  • Please read the standards first before trying to teach something about the standard. The C11 version is very clear about that the second release (i.e. C99) has been withdrawn with the new release. You might think about **versions**. That is something different and you might want to learn about that before telling more experienced people to shut up. In case you didn't know: Neither gcc nor clang defined what C standard is. That is done by the corresponding IEEE working group. But as you apparently know the documentation that well: what did you find out yourself? – too honest for this site Aug 08 '16 at 03:00
  • 3
    @Olaf: Please stop being rude. – Keith Thompson Aug 08 '16 at 03:01
  • @KeithThompson: Please read the foreword: The term "cancels" is quite clear and implies with the release of C11 C99 was not standard anymore. That is common practice with standards and avoids confusion. http://port70.net/~nsz/c/c11/n1570.html#Forewordp6 I did not say the compilers don't support older versions. It is just that they are not standard. – too honest for this site Aug 08 '16 at 03:02
  • @KeithThompson: It is not me being rude. I just reply in the same tone as OP. – too honest for this site Aug 08 '16 at 03:03
  • 3
    @Olaf: IEEE has nothing to do with the C or C++ standard; both are published by ISO. ISO has stated that the previous editions of the standard are obsolete. In what sense is that statement binding on anyone else? Someone who chooses to use an older edition of a language standard **is permitted to do so**. And again, there are existing current standards, some published by ISO, that normatively depend on older versions of the C standard. – Keith Thompson Aug 08 '16 at 03:06
  • @KeithThompson: Yes, sorry, I errorneously wrote IEEE. It is ISO, of course (wrote that in my first comment actually). They did not just state they are obsolete (which imlies they are still valid), but explicitly **canceled** those versions. Re. binding: Well, a compiler can implement anythig it wants (I use happily some gcc extensions). But it is not _standard C_ anymore. It might still be a norm, though. (Where did I write they may not be used anymore? ESL, but afaik "should" is just a recommendation - please excuse me if I learned that wrong. – too honest for this site Aug 08 '16 at 03:17
  • 7
    @Olaf It seems really odd to me that on a site whose purpose is to help others with problems, what seems to be a fairly straightforward question gets turned into a treatise on semantics. Could all of this have been avoided if I'd have simply said "C89 and C++98 language versions" instead of "C89 and C++98 language standards"? I just don't understand why some people get their kicks nitpicking things like this instead of simply seeing the obvious intent. I'm also aware that the older "versions" (not standards) are outdated, but there are many reasons programmers might have to adhere to them. – BenevolentDeity Aug 08 '16 at 06:25
  • 1
    @BenevolentDeity: I C the word `static` makes a great difference. As does the word "version" makes a great difference when it comes to standards (it is not just programming. Maybe you missed the idea about comments; they are to add information to the question, corrections, etc. I did not expect this to generate such a discussion. Similarily, the word "should" is important here. I did tell you have to use C11 (resp. C++11/14) only, but that was a strong recommendation. Note also that C99->C11 require different warnings/errors than C90, thus "standard" and C89 are missleading, too. – too honest for this site Aug 08 '16 at 12:18
  • @Olaf My point was simply that my question was easily understandable as stated. But I give... You win! – BenevolentDeity Aug 08 '16 at 19:12

1 Answers1

2

Your code is invalid, and the behavior is undefined, so the compiler can do anything also when compiling. The implicitly declared int strlen(char*) is not compatible with size_t strlen(const char *).

Has Clang changed the meaning of -pedantic-errors from the meaning used by GCC, or am I misinterpreting something?

As I read it, yes. From clang documentation:

-pedantic-errors

    Error on language extensions.

In GCC:

-pedantic

    Issue all the warnings demanded by strict ISO C and ISO C++ [...]

-pedantic-errors

    Give an error whenever the base standard (see -Wpedantic) requires a diagnostic, in some cases where there is undefined behavior at compile-time and in some other cases that do not prevent compilation of programs that are valid according to the standard.

Clang errors on extensions.

GCC errors when standard explicitly requires it and in other "some cases".

This is a different, it is a different set of errors. Standard may not require a diagnostic, but it's still an extension - GCC will be silent, Clang will error.

What is the best set of options that will enforce adherence to the selected standard and will issue errors for all non-conforming code?

The first answer that comes to mind is: "none". Compiler inherently use "implementation-defined behavior" and extension, because they are meant to compile the code in the first place, not meant to not compile non-conforming code. There are cases where the code is conforming, but still the behavior differs between compilers - you can explore such a case here.

Anyway, keep using -pedantic-errors, as it seems to work in detection of non-conforming code. Your code is invalid, the behavior is undefined, so your code is non-conforming, so clang properly detects it. Also use linters and sanitizers to detect other cases of undefined behavior.

If I continue to use -pedantic-errors with Clang is there a way to get it to issue a warning instead of an error in specific cases?

Use -fno-builtin.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
KamilCuk
  • 120,984
  • 8
  • 59
  • 111