Re: [LAD] G++ trouble
Am 16.11.20 um 10:37 schrieb Alexandre DENIS: > > I've already seen this strange behavior with gcc 9.x : symbols with > a const definition are by default not publicly visible. It works > if you explicitly add an "extern" in the definition: > > extern const float svcoeff44 [216] = (...) > > I am not sure whether it is a bug in gcc or a strict application of the > standard. It's standard behavior, but have only found it on https://en.cppreference.com/w/cpp/language/cv#Notes The const qualifier used on a declaration of a non-local non-volatile non-template (since C++14) non-inline (since C++17) variable that is not declared extern gives it internal linkage. This is different from C where const file scope variables have external linkage. Uwe ___ Linux-audio-dev mailing list Linux-audio-dev@lists.linuxaudio.org https://lists.linuxaudio.org/listinfo/linux-audio-dev
Re: [LAD] G++ trouble
On Mon, 16 Nov 2020 16:31:18 +0100 Fons Adriaensen wrote: >or > >* Just #define it in a header (e.g. globals.h) instead of creating > a variable. > > >Ciao, > Thanks again. I've gone for this options. It keeps these together, along with a bunch of enums so they're easy to find. -- It wasn't me! (Well actually, it probably was) ... the hard part is not dodging what life throws at you, but trying to catch the good bits. ___ Linux-audio-dev mailing list Linux-audio-dev@lists.linuxaudio.org https://lists.linuxaudio.org/listinfo/linux-audio-dev
Re: [LAD] G++ trouble
On Mon, Nov 16, 2020 at 01:38:01PM +, Will J Godfrey wrote: > I just did a search of the whole of src. It's *used* about a dozen times > across 5 otherwise unrelated .cpp files, but is only defined here. Just to be > certain, I did a make clean before trying this again, and it's definitely > saying > multiple defs As I understand things, extern int x; extern const int x; _declare_ x. That means it tells the compiler that x is _defined_ (as below) somewhere else. It does not create x. OTOH int x; int x = 123; const int x = 123; _define_ x. That means that a variable 'x' is created. If this is done at global scope (i.e. not inside a function or class), and there is more than one such definition, you should get a 'multiple definition' error from the linker. If there is no such definition, you should get an 'undefined' linker error if any compilation unit refers to x. So you should have _exactly_ one definition (this is why definitions should not be in a header file), and you can have as many declarations as needed. For things like your ADD_COLOUR, there are two approaches: * define and initialise it as a 'const int' in single compilation unit (e.g. globals.cpp), and declare it as external in a header file (e.g. globals.h) that gets included by all other compilation units that need it. or * Just #define it in a header (e.g. globals.h) instead of creating a variable. Ciao, -- FA ___ Linux-audio-dev mailing list Linux-audio-dev@lists.linuxaudio.org https://lists.linuxaudio.org/listinfo/linux-audio-dev
Re: [LAD] G++ trouble
On Mon, 16 Nov 2020 14:52:53 +0100 Alexandre DENIS wrote: >On Mon, 16 Nov 2020 13:38:01 + >Will J Godfrey wrote: > >> Not wishing to hijack this thread but I'm still confused :( >> >> I just did a search of the whole of src. It's *used* about a dozen >> times across 5 otherwise unrelated .cpp files, but is only defined >> here. Just to be certain, I did a make clean before trying this >> again, and it's definitely saying multiple defs >> >> e.g >> /usr/bin/ld: >> CMakeFiles/yoshimi.dir/UI/WidgetMWSlider.cpp.o:(.rodata+0x0): >> multiple definition of `ADD_COLOUR'; >> CMakeFiles/yoshimi.dir/Interface/InterChange.cpp.o:(.rodata+0x1840): >> first defined here >> >> This happens at the linker stage. >> >> Also, I thought the whole idea of putting things like this in a >> #ifndef/#def block was to ensure it was only set once. >> > >It is only set once *per file* which includes the header. But since the >symbol is extern, the linker sees one public copy per file, which >conflict with each other. > >-a. > Thanks. Clear now. Some reorganisation needed :( -- It wasn't me! (Well actually, it probably was) ... the hard part is not dodging what life throws at you, but trying to catch the good bits. ___ Linux-audio-dev mailing list Linux-audio-dev@lists.linuxaudio.org https://lists.linuxaudio.org/listinfo/linux-audio-dev
Re: [LAD] G++ trouble
On Mon, 16 Nov 2020 13:38:01 + Will J Godfrey wrote: > Not wishing to hijack this thread but I'm still confused :( > > I just did a search of the whole of src. It's *used* about a dozen > times across 5 otherwise unrelated .cpp files, but is only defined > here. Just to be certain, I did a make clean before trying this > again, and it's definitely saying multiple defs > > e.g > /usr/bin/ld: > CMakeFiles/yoshimi.dir/UI/WidgetMWSlider.cpp.o:(.rodata+0x0): > multiple definition of `ADD_COLOUR'; > CMakeFiles/yoshimi.dir/Interface/InterChange.cpp.o:(.rodata+0x1840): > first defined here > > This happens at the linker stage. > > Also, I thought the whole idea of putting things like this in a > #ifndef/#def block was to ensure it was only set once. > It is only set once *per file* which includes the header. But since the symbol is extern, the linker sees one public copy per file, which conflict with each other. -a. pgpgkvYhUvSN1.pgp Description: OpenPGP digital signature ___ Linux-audio-dev mailing list Linux-audio-dev@lists.linuxaudio.org https://lists.linuxaudio.org/listinfo/linux-audio-dev
Re: [LAD] G++ trouble
On Mon, 16 Nov 2020 13:35:30 +0100 Fons Adriaensen wrote: >On Mon, Nov 16, 2020 at 12:22:54PM +, Will J Godfrey wrote: > >> In GCC 8.3 doing that in a globally included header actually *creates* a >> multiple definitions error! >> >> #ifndef GLOBALS_H >> #define GLOBALS_H >> >> const unsigned int ADD_COLOUR = 0xdfafbf00; fine > >Putting a definition in a header file is usually a bad idea. >What you get from this (without 'extern' is a separate copy >in each file that includes the header. GCC 8 will not flag >this as an error. > >> extern const unsigned int ADD_COLOUR = 0xdfafbf00; boom! > >This normally should not create ADD_COLOUR, just tell the >compiler that it exists somewhere. So this should result >in an 'undefined' error. > >If OTOH you get a 'multiple definition' error that would >normally mean there are other definitions as well. Maybe >you had this in a number of files, decided later to make >it a single global, and forgot to delete the originals ? > >Ciao, > Not wishing to hijack this thread but I'm still confused :( I just did a search of the whole of src. It's *used* about a dozen times across 5 otherwise unrelated .cpp files, but is only defined here. Just to be certain, I did a make clean before trying this again, and it's definitely saying multiple defs e.g /usr/bin/ld: CMakeFiles/yoshimi.dir/UI/WidgetMWSlider.cpp.o:(.rodata+0x0): multiple definition of `ADD_COLOUR'; CMakeFiles/yoshimi.dir/Interface/InterChange.cpp.o:(.rodata+0x1840): first defined here This happens at the linker stage. Also, I thought the whole idea of putting things like this in a #ifndef/#def block was to ensure it was only set once. -- It wasn't me! (Well actually, it probably was) ... the hard part is not dodging what life throws at you, but trying to catch the good bits. ___ Linux-audio-dev mailing list Linux-audio-dev@lists.linuxaudio.org https://lists.linuxaudio.org/listinfo/linux-audio-dev
Re: [LAD] G++ trouble
On Mon, Nov 16, 2020 at 12:22:54PM +, Will J Godfrey wrote: > In GCC 8.3 doing that in a globally included header actually *creates* a > multiple definitions error! > > #ifndef GLOBALS_H > #define GLOBALS_H > > const unsigned int ADD_COLOUR = 0xdfafbf00; fine Putting a definition in a header file is usually a bad idea. What you get from this (without 'extern' is a separate copy in each file that includes the header. GCC 8 will not flag this as an error. > extern const unsigned int ADD_COLOUR = 0xdfafbf00; boom! This normally should not create ADD_COLOUR, just tell the compiler that it exists somewhere. So this should result in an 'undefined' error. If OTOH you get a 'multiple definition' error that would normally mean there are other definitions as well. Maybe you had this in a number of files, decided later to make it a single global, and forgot to delete the originals ? Ciao, -- FA ___ Linux-audio-dev mailing list Linux-audio-dev@lists.linuxaudio.org https://lists.linuxaudio.org/listinfo/linux-audio-dev
Re: [LAD] G++ trouble
On Mon, 16 Nov 2020 13:02:03 +0100 Fons Adriaensen wrote: >On Mon, Nov 16, 2020 at 12:24:10PM +0100, Kjetil Matheussen wrote: > >> 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. > >But > >* I _do_ have 'extern' in the header file, and >* the header file is included in only one .cc file. > >Alexandre: > >Using 'extern' in a _definition_ seems like a contradiction to me... >So for now I assume it's a G++ bug. > >Thanks to both of you, > That's weird. In GCC 8.3 doing that in a globally included header actually *creates* a multiple definitions error! #ifndef GLOBALS_H #define GLOBALS_H const unsigned int ADD_COLOUR = 0xdfafbf00; fine extern const unsigned int ADD_COLOUR = 0xdfafbf00; boom! -- It wasn't me! (Well actually, it probably was) ... the hard part is not dodging what life throws at you, but trying to catch the good bits. ___ Linux-audio-dev mailing list Linux-audio-dev@lists.linuxaudio.org https://lists.linuxaudio.org/listinfo/linux-audio-dev
Re: [LAD] G++ trouble
On Mon, Nov 16, 2020 at 12:59 PM Roman Sommer wrote: > > Kjetil Matheussen writes: > > > > Yeah, I just read this: https://gcc.gnu.org/gcc-10/porting_to.html > > > > " > > > > C language issues > > > > Default to -fno-common > > > > 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. If tentative definitions > > of particular variables need to be placed in a common block, > > __attribute__((__common__)) can be used to force that behavior even in > > code compiled without -fcommon. As a workaround, legacy C code where > > all tentative definitions should be placed into a common block can be > > compiled with -fcommon. > > > > int x; // tentative definition - avoid in header files > > > > extern int y; // correct declaration in a header file > > " > > > > > > Guess that could explain it. > > Hm? Why would that explain this behaviour? > It seems to me Fons already (correctly) uses "extern" in his header Guess you're right. I didn't read the posts very thoroughly. That's also why I wrote "could' and not "would". ___ Linux-audio-dev mailing list Linux-audio-dev@lists.linuxaudio.org https://lists.linuxaudio.org/listinfo/linux-audio-dev
Re: [LAD] G++ trouble
On Mon, Nov 16, 2020 at 12:24:10PM +0100, Kjetil Matheussen wrote: > 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. But * I _do_ have 'extern' in the header file, and * the header file is included in only one .cc file. Alexandre: Using 'extern' in a _definition_ seems like a contradiction to me... So for now I assume it's a G++ bug. Thanks to both of you, -- FA ___ Linux-audio-dev mailing list Linux-audio-dev@lists.linuxaudio.org https://lists.linuxaudio.org/listinfo/linux-audio-dev
Re: [LAD] G++ trouble
Alexandre DENIS: > On Mon, 16 Nov 2020 09:43:42 +0100 > Fons Adriaensen wrote: > > > Hello all, > > > > I'm having a strange problem with G++... > > > > In one source file 'fb3data.cc', I define arrays like this: > > > > const float svcoeff44 [216] = > > { > > 1.631996e-03, 6.335480e-02, ... > > ... > > }; > > > > (...) > > /usr/bin/ld: filtbank3.o: warning: relocation against `svcoeff88' > in > > read-only section `.text' > > Hi, > > I've already seen this strange behavior with gcc 9.x : symbols with > a const definition are by default not publicly visible. It works > if you explicitly add an "extern" in the definition: > > extern const float svcoeff44 [216] = (...) > > I am not sure whether it is a bug in gcc or a strict application of the > standard. Yeah, I just read this: https://gcc.gnu.org/gcc-10/porting_to.html " C language issues Default to -fno-common 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. If tentative definitions of particular variables need to be placed in a common block, __attribute__((__common__)) can be used to force that behavior even in code compiled without -fcommon. As a workaround, legacy C code where all tentative definitions should be placed into a common block can be compiled with -fcommon. int x; // tentative definition - avoid in header files extern int y; // correct declaration in a header file " Guess that could explain it. ___ Linux-audio-dev mailing list Linux-audio-dev@lists.linuxaudio.org https://lists.linuxaudio.org/listinfo/linux-audio-dev
Re: [LAD] G++ trouble
On Mon, 16 Nov 2020 09:43:42 +0100 Fons Adriaensen wrote: > Hello all, > > I'm having a strange problem with G++... > > In one source file 'fb3data.cc', I define arrays like this: > > const float svcoeff44 [216] = > { > 1.631996e-03, 6.335480e-02, ... > ... > }; > > (...) > /usr/bin/ld: filtbank3.o: warning: relocation against `svcoeff88' in > read-only section `.text' Hi, I've already seen this strange behavior with gcc 9.x : symbols with a const definition are by default not publicly visible. It works if you explicitly add an "extern" in the definition: extern const float svcoeff44 [216] = (...) I am not sure whether it is a bug in gcc or a strict application of the standard. -a. pgp1qeiE83ZDt.pgp Description: OpenPGP digital signature ___ Linux-audio-dev mailing list Linux-audio-dev@lists.linuxaudio.org https://lists.linuxaudio.org/listinfo/linux-audio-dev
[LAD] G++ trouble -- correction
Hello again, This is the correct version: (I typed this in manually instead of copy/paste...) const float *c; switch (fsam) { case 44100: c = svcoeff44; break; case 48000: c = svcoeff48; break; ... } Ciao, -- FA ___ Linux-audio-dev mailing list Linux-audio-dev@lists.linuxaudio.org https://lists.linuxaudio.org/listinfo/linux-audio-dev
[LAD] G++ trouble
Hello all, I'm having a strange problem with G++... In one source file 'fb3data.cc', I define arrays like this: const float svcoeff44 [216] = { 1.631996e-03, 6.335480e-02, ... ... }; There are five of these. In 'fbdata3.h' I have extern const float svcoeff44 [216]; extern const float svcoeff48 [216]; extern const float svcoeff88 [216]; ... Finally in 'filtbank3.cc' there is const float *c; switch (fsam) { case 44100: c = cvcoeff44; break; case 48000: c = cvcoeff48; break; ... } Everything compiles without errors or warnings, but the linking step fails: /usr/bin/ld: filtbank3.o: warning: relocation against `svcoeff88' in read-only section `.text' /usr/bin/ld: filtbank3.o: in function `VocFiltbank::init(int)': filtbank3.cc:(.text+0x159): undefined reference to `svcoeff192' /usr/bin/ld: filtbank3.cc:(.text+0x1d3): undefined reference to `svcoeff48' /usr/bin/ld: filtbank3.cc:(.text+0x1e3): undefined reference to `svcoeff96' /usr/bin/ld: filtbank3.cc:(.text+0x1f3): undefined reference to `svcoeff44' /usr/bin/ld: filtbank3.cc:(.text+0x1ff): undefined reference to `svcoeff88' /usr/bin/ld: warning: creating DT_TEXTREL in a PIE collect2: error: ld returned 1 exit status When I put the arrays in 'filtbank3.cc' instead, everything works. Any hints ?? Ciao, -- FA ___ Linux-audio-dev mailing list Linux-audio-dev@lists.linuxaudio.org https://lists.linuxaudio.org/listinfo/linux-audio-dev