This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
extern const and all that
- From: Gabriel Dos Reis <gdr at integrable-solutions dot net>
- To: gcc at gcc dot gnu dot org
- Cc: Zack Weinberg <zack at codesourcery dot com>
- Date: 10 Jun 2005 02:09:01 +0200
- Subject: extern const and all that
Hi,
In the message
http://gcc.gnu.org/ml/gcc/2005-05/msg01265.html
you said
> Fifth, there is a slight difference between "const" in C and in C++.
> In C++, a const variable implicitly has an internal linkage; so a
> C++ compiler tends to optimize it out when its address is not taken
> (so no storage is wasted). This is an issue for the objects
> automatically generated by the gengtype support machinery. The are
> supposed to have external linkage, so we need to explicitly say
> "extern" in their definitions.
Presumably such constants are declared in some header file, with
external linkage. It would be better to make that declaration visible
at the point of definition, rather than marking up the declarations with
'extern'.
However, if you try to compile the souces (augmented with attched
patch) with g++, you should hit an "undefined reference to symbol"
linker error similar to:
g++ -g -O2 -DIN_GCC -W -Wall -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes -pedantic -Wno-long-long -Wno-variadic-macros -Wold-style-definition -fno-common -DHAVE_CONFIG_H -DGENERATOR_FILE -o build/genmddeps \
build/genmddeps.o build/gensupport.o build/dummy-conditions.o build/rtl.o build/read-rtl.o build/ggc-none.o build/min-insn-modes.o \
build/errors.o ../build-i686-pc-linux-gnu/libiberty/libiberty.a
build/gensupport.o(.text+0xc27): In function `maybe_eval_c_test(char const*)':
/home/gdr/redhat/egcs/gcc/gensupport.c:1122: undefined reference to `insn_elision_unavailable'
build/gensupport.o(.text+0x105d): In function `init_md_reader_args_cb(int, char**, bool (*)(char const*))':
/home/gdr/redhat/egcs/gcc/gensupport.c:975: undefined reference to `n_insn_conditions'
build/gensupport.o(.text+0x108d):/home/gdr/redhat/egcs/gcc/gensupport.c:977: undefined reference to `insn_conditions'
collect2: ld returned 1 exit status
This is an instance of the situations I reported earlier.
Of course, your suggestion is the natural choice, if we did not have
addiional constraint. Indeed, the file (for MD gen-support machinery)
that defines those variables is dummy-conditions.c, with the following
comment:
/* In order to avoid dragging in all the headers that are needed to
declare things that gensupport.h uses, we duplicate the declaration
of struct c_test here. (In particular we do not want to have to
include tm.h nor rtl.h in this file.) */
Given that constraint, it appears to me that putting "extern" in the
definition is the minimal, viable solution.
Thoughts?
-- Gaby
Index: ChangeLog
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ChangeLog,v
retrieving revision 2.9112
diff -p -r2.9112 ChangeLog
*** ChangeLog 9 Jun 2005 22:27:41 -0000 2.9112
--- ChangeLog 9 Jun 2005 22:57:51 -0000
***************
*** 1,3 ****
--- 1,9 ----
+ 2005-06-09 Gabriel Dos Reis <gdr@cs.tamu.edu>
+
+ * gensupport.c (lookup_predicate): Add explicit cast to
+ htab_find() value.
+ (init_predicate_table): Use XCNEW.
+
Index: gensupport.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gensupport.c,v
retrieving revision 1.62
diff -p -r1.62 gensupport.c
*** gensupport.c 26 Apr 2005 00:23:54 -0000 1.62
--- gensupport.c 9 Jun 2005 22:57:51 -0000
*************** lookup_predicate (const char *name)
*** 1200,1206 ****
{
struct pred_data key;
key.name = name;
! return htab_find (predicate_table, &key);
}
void
--- 1200,1206 ----
{
struct pred_data key;
key.name = name;
! return (pred_data *) htab_find (predicate_table, &key);
}
void
*************** init_predicate_table (void)
*** 1289,1295 ****
for (i = 0; i < NUM_KNOWN_OLD_PREDS; i++)
{
! pred = xcalloc (sizeof (struct pred_data), 1);
pred->name = old_preds[i].name;
for (j = 0; old_preds[i].codes[j] != 0; j++)
--- 1289,1295 ----
for (i = 0; i < NUM_KNOWN_OLD_PREDS; i++)
{
! pred = XCNEW (struct pred_data);
pred->name = old_preds[i].name;
for (j = 0; old_preds[i].codes[j] != 0; j++)