13

I work on a code base which is mostly C with a little C++, and is mostly built with gcc but occasionally it needs to be built with MSVC. Microsoft's C compiler is still pretty much C89 with a few minor extensions, and it still doesn't support mixed code and variable definitions à la C++/C99. So I need to find a way to prevent developers from writing out-of-order code/variable definitions while they are working with gcc, otherwise the build subsequently breaks with MSVC. If I use gcc -std=c89 then everything breaks because C++-style comments are not allowed (there may be other issues too, but I haven't looked into this any further). If I use gcc -std=gnu89 then the out-of-order code/variable definitions are allowed, so that doesn't help me either. Any ideas ? I guess I just need something like gcc -std=c99 -fno-inline-variable-definitions, if such an option existed.

Kate Gregory
  • 18,808
  • 8
  • 56
  • 85
Paul R
  • 208,748
  • 37
  • 389
  • 560

3 Answers3

13

You're after the -Wall -Wextra -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-declarations and -Wdeclaration-after-statement options, as described on the gcc warnings info page. Note that these can cause a lot of noise from issues in system header files, and they're only warnings so you've got to have a policy of being keen to have a zero-warning build.

Donal Fellows
  • 133,037
  • 18
  • 149
  • 215
  • Thanks - I hadn't spotted `-Wdeclaration-after-statement` - that should help a little - now all I have to do is make sure that the developers fix all their warnings. – Paul R Jun 23 '10 at 08:26
  • 10
    You can do `-Wdeclaration-after-statement -Werror=declaration-after-statement` to turn it into an error. – Matthew Flaschen Jun 23 '10 at 08:29
  • @Matthew: Now that's a snippet I didn't know. – Donal Fellows Jun 23 '10 at 09:00
  • @Matthew: that would be a perfect solution but it doesn't seem to work with gcc 4.0 or 4.2. – Paul R Jun 23 '10 at 09:14
  • 3
    @Paul, yes that seems to be [Bug 35058](http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35058). It says it was fixed in GCC 4.4, which is what I'm using. I guess until you can upgrade you can kill the build by grepping for that warning. – Matthew Flaschen Jun 23 '10 at 09:46
  • @Matthew: thanks - it looks like gcc 4.2 accepts -Werror=XXX but treats it just the same as -Wxxx, but gcc 4.0 just chokes. Anyway grepping for the warnings at least gives me something useful even if it's not a complete solution. – Paul R Jun 23 '10 at 13:03
3

I don't believe there is a way to do what you want. The dialect of C supported by MSVC is closer to C89 than C99 (eg. it doesn't support designated initializers either); you really want something more akin to C89-with-C++-comments-and-inline-keyword.

The problem with that is that C++ comments can affect the correctness of valid C89 code. For example, the meaning of this line changes substantially:

int a = 10//* foo */2;

I'd say your best bet is to enforce C89 in your C source files, including C89-style comments. inline is probably OK, though: you can define it to __inline on gcc.

caf
  • 233,326
  • 40
  • 323
  • 462
  • The other answer works, but I think it's likely too fiddly. I like this answer better. Just don't use C++ style comments. – Omnifarious Jun 23 '10 at 08:09
  • Unfortunately this is a large code base with a lot of developers - doing a mass search-and-replace on the comments would be a major effort (especially all the source control issues that would result from this) and the developers would probably revolt if forced to use old-style C comments. There may also be other C89 restrictions that we could not work around. We *really* need GNU89 or C99, but without the C++-style variable declarations which cause MSVC to barf. – Paul R Jun 23 '10 at 08:23
1

It is not Win32 that renders the code uncompilable, but the compiler. You can use GCC on Win32 and get greater cross-platform compatibility.

Another possibility is to use C++ compilation for your Win32 build; the GCC compilation will already have determined that it is valid C, and C++ compilation will generally make it stronger C too.

[edit] Another solution is to use a continuous integration server such as CruiseControl configured so that whenever the GCC platform coders check-in code, the CI server can check it out and build it using VC++ (or even apply a third-party static analysis tool) and on error e-mail the results to the user who checked in the erroneous code. This solution may be heavyweight for the original problem, but may yield many other benefits besides.

Clifford
  • 88,407
  • 13
  • 85
  • 165
  • `gcc -std=c89` does **NOT** allow C++-style comments, hence this is not a workable solution. – Paul R Jun 23 '10 at 08:21
  • @Paul R: Sorry Paul I deleted that statement before you posted the comment (and after I read your post more carefully). – Clifford Jun 23 '10 at 08:24
  • @Clifford - no problem - downvote removed. C++ compilation is probably not an option though - we would need to make a lot of changes to the code base, e.g. casting the result of calls to malloc and dealing with many other subtle differences between C and C++. – Paul R Jun 23 '10 at 09:12
  • 1
    The *stronger C* claim is interesting. What does it mean? For example, casting void pointers makes it "weaker C" for me. – u0b34a0f6ae Jun 23 '10 at 12:09
  • kaizer.se: C++ is more strongly typed. In C++ if you cast a void* then assign it to a different pointer type it will not compile. In C you may just get a warning. It is usual therefore not to cast a void* in C an let the compiler figure it out. There is an argument for casting merely for C++ compatibility and make sure the warning is enabled and set to trigger an error. But I agree it is an issue; to perhaps compromise the C code for C++ compatibility may not on balance be wise. – Clifford Jun 23 '10 at 16:54
  • 1
    @Clifford: I think you should always know what computer language you're writing in, and write for that language. The problem in writing in the intersection of C89 and C++ is that you get bad code in two languages. – David Thornley Jun 23 '10 at 17:25
  • 1
    @David Thornley: Probably, it was a suggestion for consideration, not a recommendation. You could of course say the same for C89/C99. If Paul's coders write in C89 there would be no problem! But in fact he (not unreasonably) wants C89 variables with C99 comments, so is already coding across two standards. – Clifford Jun 24 '10 at 08:07