Compiling source code on 2 different versions of gcc

I am compiling my source code on two different machines that use different versions of gcc.

cflags c89

-Wall -Wextra -Wunreachable-code -g -m32 -D_DEBUG -O0 -D_LARGEFILE64_SOURCE -D_REETRANT -D_THREAD_SAFE 

One of them is redhat-4.

 gcc (GCC) 4.1.2 20080704 (Red Hat 4.1.2-46) Linux 203_test_server 2.6.18-164.el5 #1 SMP Tue Aug 18 15:51:48 EDT 2009 x86_64 x86_64 x86_64 GNU/Linux 

And one of them is Fedora 18

 gcc (GCC) 4.7.2 20121109 (Red Hat 4.7.2-8) Linux localhost.localdomain 3.8.1-201.fc18.x86_64 #1 SMP Thu Feb 28 19:23:08 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux 

My build fedora 18 is error free. However, there are some errors on the redhat 4 machine.

 channel.h:35: error: redefinition of typedef 'channel_t' internal.h:19: error: previous declaration of 'channel_t' was here 

I think a mistake is just a circular problem. However, with the same code base compiled on two different machines, can there really be a difference using two different versions of gcc?

I thought using a newer version of the compiler would cause more errors, since a newer compiler might be more strict.

This is not a matter of resolving the error, but a general question about compilers.

Are there any flags that I can set to avoid this in the future. Maybe if compiling on this version of gcc does this, if the versions are not compatible?

+7
source share
6 answers

This is a duplicate: Why is the "Typedef Override" error with GCC 4.3 but not GCC 4.6?

The answer is that gcc has been modified to modify this check.

http://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=ce3765bf44e49ef0568a1ad4a0b7f807591d6412

Sometimes warnings for behavior that are defined in the language but are considered bad are considered too strict because some useful and / or harmless use cases are included in the warning. Then the compiler developers try to fix the opposite, that is, reduce the number of warnings. In this case, the change made the warning appear only when the second definition changed the typedef to a different but compatible type.

Another current example is -Wshadow in gcc 4.8 has just been announced. The release note states that -Wshadow will no longer warn if a function name is obscured by another.

See: http://gcc.gnu.org/gcc-4.8/changes.html

Edit: how can you avoid this: either remove one of the definitions, or transfer it to a separate include file and delete both of the other definitions.

+4
source

It depends on which headers are included in the source code. If you are connecting to external libraries, your source code may not be compatible with the version of the library installed on the old system.

If the source code does not contain the headers of external libraries (except the C library), then there may be preprocessor directives that need to be changed.

EDIT:

After a Google search, the channel_t message from the kernel header appears. You are using kernel releases that are far apart on two machines. If the code depends on the kernel header file, it may well be necessary to have a newer version of the kernel than on a Red Hat machine. You did not indicate what the code is (is it a device driver?) Or what files does it include, so it's hard to say more.

+10
source

Compare the contents of channel.h and internal.h on two systems where you get different results. I doubt this is a gcc version. Most likely, errors are the result of code changes for these files over time, for example, when one system has a newer version of the library and its associated header files than others.

+4
source

First, let's talk a little about your problem. I think that the most likely cause of your system, giving errors in one system over another, is code that is not identical; you can check this with any tool or diff to find any minor changes that appear in your code base. Usually, when Ive seen problems with this type of error, you have something like:

 typedef struct Foo* Fooptr; 

In the header file, and then:

 typedef struct Foo { int bar; } *Fooptr; 

in the source file. This means that you can just remove the typedef in the source, and everything should be fine. Just looking for something.

Now, if this is a gcc problem, the second option to solve your problem is to be able to have multiple versions of gcc on the same computer , and then specify the exact version of gcc to run with the -v option. Therefore, it would be nice to give a 4.1.2 shot to your Fedora 18 computer.

Another note: if you use the -v , but do not specify the gcc version to run, you will get (at the output of stderr) the commands executed to start the compilation steps. It can be useful to see what happens and if there are any significant differences between what happens on each machine.


Ok, now for your questions. Yes, there are flags to compile on "version X" gcc : First, there is __VERSION__ Predefined macro , this will return you const char * version numbers. This can be quite useful, but as stated in the gcc documentation:

You should not rely on its contents having any particular form, but you can assume that it contains at least the issue number

Despite this, Ive usually only seen one form of output from this, something like "4.6.3" if my gcc version is 4.6.3-1ubuntu5 .

Now, if you know (or suspect) that any of your code will cause errors for a specific version of gcc , you can use the predefined macros __GNUC__ , __GNUC_MINOR__ and __GNUC_PATCHLEVEL__ to protect "yourself:
Heres a short snip - it shows at the highest level how to use it:

 #if __GNC__ == 3 printf("Hello version 3.xx\n"); #elif __GNC__ == 4 printf("Hello version 4.xx\n"); #endif 

So, in the above system, where version 4.6.3 you see the message "Hello version 4.xx". Then you can get a more advanced level and check out fakes as well:

 #if __GNUC__ > 3 || \ (__GNUC__ == 3 && (__GNUC_MINOR__ > 2 || \ (__GNUC_MINOR__ == 2 && \ __GNUC_PATCHLEVEL__ > 0)) printf("I'm a gcc greater than 3.2.0\n"); #endif 

Or a cleaner version using your own macro:

 #define GCC_VERSION (__GNUC__ * 10000 \ + __GNUC_MINOR__ * 100 \ + __GNUC_PATCHLEVEL__) #if GCC_VERSION > 30200 printf("I'm a gcc greater than 3.2.0\n"); #endif 

To solve the question of whether different versions of gcc create different errors, you are right that more happens in each version of gcc , and sometimes everything changes, so you will see the differences between different versions of the compiler. It is best to check the release notes for each version between the two of you. (from 4.1 to 4.7).

I'm not sure what your target architecture is, so make sure you check these specific sections in each of the documents. But I think that you really want to take a look at "Build system improvements" and "Incompatible changes to the build system" , they also contain a section specific to C code, which can be convenient for viewing.

+1
source

There is not enough information to say exactly what is happening. I join those who say that this is hardly a problem with the compiler version.

This error occurs (obviously) when the compiler encounters two different declarations for the same name. It should not be too difficult to understand why this is happening.

Check the makefile to find the referenced internal.h and channel.h header files. The lines above will have a typedef or other declaration for channel_t . Work on these declarations for tips.

I must assume that one or both of these files are in the libraries you use. If both internal.h and channel.h are your own code, debug your own code!

Otherwise, there are many possibilities. Likely,

  • The preprocessor -D or #define ed flags are incorrect, so multiple declarations are compiled when only one should be.

  • Two different libraries or standard headers and the library have a clash of names.

  • There is a collision with a library or a standard header in your own code. If channel_t is the type you defined, this is the problem. You should not define your own types ending in _t , because they are reserved for implementation.

Number 1 above can occur in several ways, but the most common is incorrect library configuration. Typically, libraries should be ./configure ed for the OS on which they are used. If you configure one Linux and copy it to another, you are asking for problems like the ones you see.

Number 2 may occur on one Linux, and not on another, due to differences in the version of the library. In this case, update the machine with the error to the same versions as without errors. Remember to run ./configure .

For number 3, the fix is ​​obvious. Change the name of your type.

I see a channel.h and channel_t in Tor. My wild guess is that you are using Tor and are looking at the wrong Tor configuration on the machine with the error.

+1
source

This is not a matter of resolving the error, but a general question about Compilers.

Are there any flags that I can set to avoid this in the future.

Each particular version of the compiler will have its own keys or flags.

If the compiler version was created to receive certain switches, and one of them is the one you need to avoid certain checks of your source code, then yes, there is / will be a way to avoid this in the future.

If the compiler version, the latest or future version that you are using, does not have / does not accept the switch to avoid / skip certain checks of the source code, then there is no way to avoid this.

+1
source

All Articles