mersenneforum.org  

Go Back   mersenneforum.org > Extra Stuff > Programming

Reply
 
Thread Tools
Old 2020-12-08, 21:47   #1
bsquared
 
bsquared's Avatar
 
"Ben"
Feb 2007

2×1,789 Posts
Default gcc 10.2.0 behavior

A couple times now I have seen reports where gcc 10.2.0 failed to compile a project that older gcc versions (and icc) compiled just fine. They fail with errors in the linking stage; complaining about multiple definitions of global constants defined in headers (e.g., see here).

I know that global definitions in headers is poor form, but it will be a pain to fix if that is the only solution going forward. The headers are all protected from being included twice using the usual #ifndef X #define X macros, which have worked up until now.

Any thoughts on fixes, or ideas about what happened with this newer gcc version?
bsquared is offline   Reply With Quote
Old 2020-12-08, 22:00   #2
Nick
 
Nick's Avatar
 
Dec 2012
The Netherlands

1,747 Posts
Default

I tend to program defensively and avoid C's concept of "tentative definitions".
If a variable declaration initializes the variable then the compiler must regard it as a definition.
If a variable declaration says "extern" instead then the compiler must view it as merely a declaration
(or have they changed the rules again?)
Nick is online now   Reply With Quote
Old 2020-12-08, 23:04   #3
bsquared
 
bsquared's Avatar
 
"Ben"
Feb 2007

2·1,789 Posts
Default

Quote:
Originally Posted by Nick View Post
I tend to program defensively and avoid C's concept of "tentative definitions".
If a variable declaration initializes the variable then the compiler must regard it as a definition.
If a variable declaration says "extern" instead then the compiler must view it as merely a declaration
(or have they changed the rules again?)
I would think that has remained the same, but I don't keep up to date on these things.

For clarity, here is an example of what I'm talking about.

header1.h:
Code:
#ifndef HEADER1_H
#define HEADER1_H

/* defines */

/* typedefs */

/* function declarations */

/* globals */
int foo;
int bar;

#endif
Now, if two source files, say main.c and worker.c both #include header1.h, only one set of the globals should be defined. At least, that is how it has worked up to gcc 10.2.0.

If I have to update everything using externs to declare the globals and then define them once (probably in main.c), then so be it, but if there is a cheaper, hackier way to do what I want (compile the program as-is) then I'd like to at least consider it.
bsquared is offline   Reply With Quote
Old 2020-12-09, 01:48   #4
mathwiz
 
Mar 2019

20010 Posts
Default

Possibly helpful? https://gcc.gnu.org/gcc-10/porting_to.html

"A common mistake in C is omitting extern when declaring a global variable in a header file. If the header is included by several files it results in multiple definitions of the same variable. In previous GCC versions this error is ignored. GCC 10 defaults to -fno-common, which means a linker error will now be reported. To fix this, use extern in header files when declaring global variables, and ensure each global is defined in exactly one C file."

Last fiddled with by mathwiz on 2020-12-09 at 01:49 Reason: quote relevant part of page
mathwiz is offline   Reply With Quote
Old 2020-12-09, 03:33   #5
bsquared
 
bsquared's Avatar
 
"Ben"
Feb 2007

2·1,789 Posts
Default

Quote:
Originally Posted by mathwiz View Post
Possibly helpful? https://gcc.gnu.org/gcc-10/porting_to.html

"A common mistake in C is omitting extern when declaring a global variable in a header file. If the header is included by several files it results in multiple definitions of the same variable. In previous GCC versions this error is ignored. GCC 10 defaults to -fno-common, which means a linker error will now be reported. To fix this, use extern in header files when declaring global variables, and ensure each global is defined in exactly one C file."
Yeah, I'd say that explains it exactly. Looks like I have some work to do... in the meantime hopefully building with an earlier version of gcc is a workaround.
bsquared is offline   Reply With Quote
Old 2020-12-09, 05:26   #6
VBCurtis
 
VBCurtis's Avatar
 
"Curtis"
Feb 2005
Riverside, CA

19·263 Posts
Default

If there's a flag that "defaults to -fno-common", can't we (well, you) just set that flag the opposite way at compile time?
VBCurtis is offline   Reply With Quote
Old 2020-12-09, 12:20   #7
mathwiz
 
Mar 2019

23·52 Posts
Default

Quote:
Originally Posted by VBCurtis View Post
If there's a flag that "defaults to -fno-common", can't we (well, you) just set that flag the opposite way at compile time?
Perhaps, but it seems like sticking in the extern's is the more syntactically correct approach, and should work with all gcc versions without the need to fiddle with compiler flags...
mathwiz is offline   Reply With Quote
Old 2021-01-17, 16:38   #8
EdH
 
EdH's Avatar
 
"Ed Hall"
Dec 2009
Adirondack Mtns

32×5×89 Posts
Default

Quote:
Originally Posted by VBCurtis View Post
If there's a flag that "defaults to -fno-common", can't we (well, you) just set that flag the opposite way at compile time?
The page referenced earlier does suggest:
Quote:
Originally Posted by Porting to GCC 10
As a workaround, legacy C code where all tentative definitions should be placed into a common block can be compiled with -fcommon.
I have tried using this flag in a variety of places within the YAFU Makefile, with no success.

Quote:
Originally Posted by mathwiz View Post
Perhaps, but it seems like sticking in the extern's is the more syntactically correct approach, and should work with all gcc versions without the need to fiddle with compiler flags...
The error file from a compile attempt resulted in 3876 "multiple definitions." This represents a substantial amount of work to resolve by editing to include "extern."

I am looking at a project to write a script to do all this editing based on the list of multiple definitions. But, my concern is that all the first instances of each definition did not flag the error. Should all those instances also include "extern," or, is a single point that doesn't, have to exist? If the latter, is there a correct place for the initial definition, such as the main code block?
EdH is offline   Reply With Quote
Old 2021-01-17, 17:57   #9
EdH
 
EdH's Avatar
 
"Ed Hall"
Dec 2009
Adirondack Mtns

32·5·89 Posts
Default

In some small playing, this appears beyond my capabilities and apparently not within my understanding, either. I tried to use extern for a couple of the "multiple definitions," but there are no second instances of declaration. If I "extern" the one reference, I get "undefined references." If I add a definition to the offended file, it does appear to fix that one issue, but I have no understanding of Ben's intricacies of the YAFU code and the editing is not scriptable from my point of view. Although not fully abandoned, I do not expect to play with this very much more, at least for now.
EdH is offline   Reply With Quote
Old 2021-01-17, 18:27   #10
ldesnogu
 
ldesnogu's Avatar
 
Jan 2008
France

2·52·11 Posts
Default

A trick is to play with #define extern.
ldesnogu is offline   Reply With Quote
Old 2021-01-17, 18:50   #11
bsquared
 
bsquared's Avatar
 
"Ben"
Feb 2007

2×1,789 Posts
Default

I am actively working on this.
bsquared is offline   Reply With Quote
Reply

Thread Tools


Similar Threads
Thread Thread Starter Forum Replies Last Post
P-1, 4GB RAM on 32 bit OS, odd behavior PageFault Software 2 2012-05-06 00:58
Don't understand this mfaktc behavior Chuck GPU Computing 2 2011-06-18 17:24
Question about P-1 behavior JuanTutors Software 0 2006-11-18 02:49
Strange Computer Behavior jinydu Lounge 23 2004-06-08 09:00
Strange behavior on 1.7G Celeron willmore Software 0 2002-09-09 20:17

All times are UTC. The time now is 09:37.


Fri Oct 22 09:37:09 UTC 2021 up 91 days, 4:06, 1 user, load averages: 1.32, 1.32, 1.36

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2021, Jelsoft Enterprises Ltd.

This forum has received and complied with 0 (zero) government requests for information.

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation.
A copy of the license is included in the FAQ.