Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

visibility effects of "const"

29 views
Skip to first unread message

jacobnavia

unread,
Nov 11, 2015, 3:34:55 PM11/11/15
to
Consider this file

int FRA = 1;

And this other file:

#include <cstdio>
extern const int FRA;
int main(void)
{
printf("FOO=%d\n", FRA);
}

OUTPUT:

1

Now, if I change the first file like this:

const int FRA = 1;

~/tmp $ g++ c.cpp d.cpp
Undefined symbols for architecture x86_64:
"_FRA", referenced from:
_main in d-6da259.o
ld: symbol(s) not found for architecture x86_64

Note that when the "const" is absent, the declaration in the second file
(the one with the main function) does NOT correspond to the declaration
of the first file.

Only if I define the integer as mutable (not const) the link works.

?????????????

Thanks for your time.

jacob

Bo Persson

unread,
Nov 11, 2015, 4:02:07 PM11/11/15
to
You should have the "extern" in a header, and include that in both
source files. Otherwise using const implies static.

Another C++ feature.



Bo Persson


jacobnavia

unread,
Nov 11, 2015, 4:05:12 PM11/11/15
to
Le 11/11/2015 22:01, Bo Persson a écrit :
> using const implies static

!!!!!!!

WOW I didn't expect that. Thanks

Paavo Helde

unread,
Nov 11, 2015, 4:08:34 PM11/11/15
to
jacobnavia <ja...@jacob.remcomp.fr> wrote in news:n208kr$tmo$1@dont-
email.me:

> Consider this file
>
> int FRA = 1;
>
> And this other file:
>
> #include <cstdio>
> extern const int FRA;
> int main(void)
> {
> printf("FOO=%d\n", FRA);
> }
>
> OUTPUT:
>
> 1
>
> Now, if I change the first file like this:
>
> const int FRA = 1;

'const' implies internal linking by default in C++ (unlike in C), so this
FRA is not visible in other files. You probably need (not tested):

extern const int FRA;
const int FRA = 1;

hth
Paavo

jacobnavia

unread,
Nov 11, 2015, 4:16:57 PM11/11/15
to
Le 11/11/2015 22:08, Paavo Helde a écrit :
> extern const int FRA;

YES, that "fixes" it.

extern const int FRA = 1;

Ahhh c++...

Thanks for your help

Ian Collins

unread,
Nov 11, 2015, 4:24:15 PM11/11/15
to
It allows one to define a const value in a header, which in C would
result in multiple definitions.

--
Ian Collins

David Brown

unread,
Nov 12, 2015, 7:16:33 AM11/12/15
to
Of course, you can do it in a clear manner that is compatible with C and
C++ by writing "static const int FRA = 1;".

At file scope (ignoring C++ namespaces), every declaration or definition
is either "extern" or "static" (though you can't put the "extern" label
directly on a definition). For some silly reason, the C founding
fathers made "extern" the default unless you actively put on "static".
For good but inconsistent reasons, the C++ founding fathers reversed
that default for objects declared "const".

My recommendation is that data and functions should either have an
extern declaration (in a header), or an explicit "static".

(Putting things in an anonymous namespace in C is effectively the same
as making them "static", IFAIUI.)

jacobnavia

unread,
Nov 12, 2015, 8:26:41 AM11/12/15
to
OK

But then you will have multiple definitions of identical static objects
in each file instead of a single definition in a single file.

For a single int the difference is negligible but for more complex data
structures it could be the source of quite a bloat in the data segment
isn't it?


David Brown

unread,
Nov 12, 2015, 9:54:16 AM11/12/15
to
It is not a problem, for two reasons.

One is that in many cases, you are talking about a simple thing like a
"const int". Because the compiler knows these cannot legally be
changed, it can use immediate addressing modes in code rather than
creating the actual const int object (and of course the value can also
be used in optimisation as it is fixed). Because the compiler knows it
has internal linkage, it does not have to create the const for other
modules - so the object is (almost) never actually created.

And if the code being compiled doesn't refer to the const object at all,
absolutely nothing gets created for it - just like a #define or enum
constant.

About the only time the const int will be created is if code takes its
address and the compiler can't optimise things away.

In cases where you have a more complex const data structure, you would
typically declare it with "extern" in the header file, and only actually
define it in one module. Then just like anything else with external
linkage, it is only created in one object file.



0 new messages