0

I am in the midst of researching possible pitfalls of migrating from Sun C 5.9 to gcc (GCC) 3.4.6 on a Solaris 10 box for consistency with our other programs. Is there any guide or list of possible pitfalls available which we should look out for?

We have already narrowed down an issue with code of the following sort (known by us to be bad practice, but long existing):

char* stringLiteralPointer = "someStringLiteralValue";
strcpy(stringLiteralPointer , "anonStringLiteralValue"); //Crash here only with gcc

This error can be detected by using -Wwrite-strings and checking all the errors. Are there any other such warnings we should be aware of that could point out more such possible run-time errors from the differences in the gcc c compiler and the Sun C compiler?

Ian T. Small
  • 304
  • 2
  • 16
  • 4
    I think what you meant is strcpy – fernando.reyes Dec 18 '13 at 21:14
  • 2
    Gcc 3.4.6 is pretty ancient as compilers go, too. – Phil Miller Dec 18 '13 at 21:15
  • I think a static code verification could make a lot of good on this situation, I recommend cppcheck that gives you a lot of insight about faulty code, not just the migration errors – fernando.reyes Dec 18 '13 at 21:19
  • 4
    GCC 3.4.6? Why? Why not a modern current version of GCC, like 4.8.2? – Jonathan Leffler Dec 18 '13 at 21:33
  • 1
    Going to GCC 3.4.6 is really a mistake. It is unsupported and old (and could be buggy on current systems). Please go to a recent GCC. – Basile Starynkevitch Dec 18 '13 at 23:07
  • My apologies, I had intended to write strcpy in the quick example code (this is paraphrased code for security reasons). More "modern" versions of GCC are not an option as I am working with what is already installed and depended upon by other applications. – Ian T. Small Dec 19 '13 at 15:17
  • 2
    Misusing writable string constants is the primary issue; it was always undefined behaviour, but Sun tended to allow it where GCC no longer does. If you're using 3.4.6 you could (yuck — I shouldn't say this) use `-fwriteable-strings` which will generate a warning that it won't be supported (it isn't available in any GCC 4.x compiler), but would leave your code working until you can fix it. But do get on with fixing it. – Jonathan Leffler Apr 16 '14 at 06:01
  • Thank you @JonathanLeffler, that's helpful advice. The program breaking errors seem to have (so far) been corrected. Hopefully we will not need to turn on this compiler issue. Currently we are working on migrating away from C anyways, as it is truly unnecessary to have the fine control of C for this program. – Ian T. Small Apr 17 '14 at 19:04

2 Answers2

4

The strlen function take just a single argument of type const char* (which means it will accept a non-const char* argument).

Some older compilers might accept function calls with an incorrect number of arguments. You need to fix the code.

That's assuming your code actually uses strlen. As fernando.reyes suggests in a comment, it's likely you really meant strcpy rather than strlen (particularly since you don't use the result; calling strlen() and discarding the result doesn't make much sense).

In that case, the problem is that stringLiteralPointer points to (the array object associated with) a string literal. Attempting to modify such an array has undefined behavior. Some compilers might put string literals in read/write memory, but you should not depend on that.

Again, the solution is to fix your code. You need to arrange for stringLiteralPointer to point to an array that's not a string literal. One way to do this is to use malloc to allocate enough space (and be sure to check that the pointer returned by malloc is non-null). If your pointer already points to a string literal, you can probably also use the non-standard strdup function, which (attempts to) allocate a new read/write copy of the string and returns a pointer to it. Again, you need to confirm that the allocation succeeded.

Another alternative might be to use an array, rather than a pointer. This:

char *ptr = "literal";

causes ptr to point to a string that you're not allowed to modify. This:

char arr[] = "literal";

makes arr an array containing a read/write copy of the string literal.

And please make sure that the code in your question is the actual code you're compiling. Copy-and-paste it, don't re-type it. Please read this.

More generally, gcc has a number of options to enable extra warnings. If you compile your code with something like:

gcc -std=c99 -Wall -Wextra -O3 ...

you'll likely catch a number of questionable things in your code. The -std=c99 option tells gcc to (attempt) to conform to the 1999 ISO C standard; if your code is meant to be compliant to C90 (commonly but incorrectly called "ANSI C"), use -ansi rather than -std=c99. The -O3 option enables the maximum level of optimization; this causes the compiler to perform additional analysis that can also enable more warnings.

There are a number of C checkers that perform even more analysis than most compilers do. Lint was the original tool. Splint (formerly LCLint) is a modern implementation, and it's freely available here or (probably) via your system's package manager.

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
-1

This error can be detected by using -Wwrite-strings and checking all the errors

strlen(stringLiteralPointer , "anonStringLiteralValue"); 

is not valid in C. I got this error without any flag (warning):

[Error] too many arguments to function 'strlen'   

Are there any other such warnings we should be aware of that could point out more such possible run-time errors from the differences in the gcc c compiler and the Sun C compiler?

In GCC, to detect more warnings you can compile your code in C99 mode (-std=C99) with -Wall and -Wextra flags.

haccks
  • 104,019
  • 25
  • 176
  • 264
  • 1
    You have made a true statement, but how does it answer the question in any way? – Rob Kennedy Dec 18 '13 at 21:16
  • @RobKennedy; Because my compiler GCC 4.8.1 detected this error without any flag. – haccks Dec 18 '13 at 21:18
  • 2
    @RobKennedy: It answers the question you asked. You showed us code that calls `strlen` with two arguments. Is that really what your code does? – Keith Thompson Dec 18 '13 at 21:20
  • 2
    I didn't ask a question here, @Keith. But the question that was asked was not about whether the `strlen` call was valid. It was about a list of pitfalls, and a list of warnings to enable. Is Haccks's answer meant to say that *no* warning flags are necessary to find *any* errors? Besides, I think Fernando is correct that it was supposed to say `strcpy`. – Rob Kennedy Dec 18 '13 at 21:23
  • @RobKennedy: Sorry, I didn't notice that you weren't the OP. And yes, the question is more general that just diagnosing a single error. – Keith Thompson Dec 18 '13 at 21:25
  • But the guy knows gcc finds errors the Solaris compiled doesn't (and he meant `strcpy` not `strlen`). He wants to know more about this kind of problem. – Gene Dec 18 '13 at 21:26
  • 4
    This proves the snipped of code is faulty, how does this helps the OP to know to migrate his code to gcc? – fernando.reyes Dec 18 '13 at 21:26
  • @RobKennedy; No. I did't mean to say that. Generally I compile my code with `-Wall` and `Wextra` to catch warnings but in this case as OP claims that: `This error can be detected by using -Wwrite-strings and checking all the errors`, that's why I answered. – haccks Dec 18 '13 at 21:26
  • @fernando.reyes; Yes it does. I answered already. – haccks Dec 18 '13 at 21:29