Does native C have common symbol?

594 Views Asked by At

In GCC10, gcc default to fno-common. That means, all tentative defined symbols are not common. I think gcc conforms to the C specification but it seems there are no common symbols in the native C program. Are common symbols only for extension syntax?

2

There are 2 best solutions below

0
On BEST ANSWER

Does native C have common symbol?

Read the C11 standard n1570. Its index don't even mention common symbols.

Read carefully also the documentation of GCC and this draft report.

Perhaps you refer to the ELF file format used on Linux for object files and executables. There you can find a mention of common symbols, which tend to be deprecated .... Read the Linux ABI specification, etc here.

My recommendation is to declare all your public symbols as extern in some header file (#include-d in most of your *.c files), and define them once (without extern) in a single translation unit. You could use simple preprocessor tricks (such as X-macros).

You might be interested in using C code generators such as lemon or SWIG, or develop your script (with GNU awk or Guile or Python or GPP etc... ....) for simple metaprogramming techniques (autoconf could be inspirational) generating some C code. Configure your build automation tool (GNU make, ninja...) suitably.

You might be interested in using static analyzer options and precompiled headers of recent GCC. Look also into Clang static analyzer and clang tidy and Frama-C.

You surely want to pass -Wall -Wextra -g -H to gcc and read How to debug small programs and Modern C.

1
On

No, it has nothing to do with "extension syntax", and it has nothing to do with "common symbols" as a language construct. It simply refers to the behavior of variable declarations at file scope.

C says that if you place a declaration like int i; in a file, and don't elaborate on it anywhere else, then it will have external linkage and it will be considered to be defined to have a value of 0. This is called a "tentative definition". Declarations with the same name in different files, if they have external linkage, all refer to the same variable. Generally the way to use external linkage is to define a variable in one file, and use an extern declaration in any other files that make use of it.

In GCC with -fcommon, tentative definitions for the same variable can appear in more than one file. GCC will resolve this at link time, and allocate storage (initialized to zero) for the variable once.

In GCC with -fno-common, tentative definitions are resolved to definitions ASAP when the file is compiled. If more than one file contains a tentative definition for a variable, then this will cause a multiple definition error at link time.

As far as I can tell, the C standard doesn't require or prohibit either behavior. In particular, C does not have C++'s "one definition rule". However, the -fno-common behavior is generally less surprising, catches a forgotten extern sooner, and allows the compiler to optimize better (because it knows exactly where the variable lives when compiling, instead of waiting to find out later). For these reasons the default was changed in GCC.