tinycc-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Tinycc-devel] Inconsistency gcc/tcc on visibility hidden


From: ag
Subject: [Tinycc-devel] Inconsistency gcc/tcc on visibility hidden
Date: Sun, 6 May 2018 19:05:31 +0300
User-agent: Mutt/1.9.4 (2018-02-28)

Hi,

Attached and for your convience is a test case, that shows that gcc and tcc
are inconsistant, with the way that treat variable declarations and when the
-fvisibility="hidden" flag has been set during compilation.
(the attached code also is inlined for comments)

I see first, that tcc parses in parse_attribute (), the visibility hidden flag,
which sets it to STV_HIDDEN.

Here is the code:

```C
/* alib.h */

int Test = 0;
__attribute__((visibility("default"))) int Testwithattr = 0;

extern __attribute__((visibility("default"))) void init_test (void);
/* end alib.h */

/* alib.c */

#include "alib.h"

extern __attribute__((visibility("default"))) void init_test () {
  Test++;
  Testwithattr++;
}
/* end alib.c */

/* compiled with:
  gcc -o liba-gcc.so alib.c -g -O2 -shared -fPIC -fvisibility="hidden"        
  tcc -o liba-tcc.so alib.c -g -O2 -shared -fPIC -fvisibility="hidden"        
 */

/* test.c */
#include <stdio.h>
#include "alib.h"

int main (int argc, char **argv) {
  init_test ();
  fprintf (stdout, "without attribute got %d\n", Test);
  fprintf (stdout, "with    attribute got %d\n\n", Testwithattr);
  return 0;
}

/* end test.c */

/* compiled with:
  gcc -o test-gcc test.c -L. -la-gcc -g -O2 -fvisibility="hidden"               
                                                      
  tcc -o test-tcc test.c -L. -la-tcc -g -O2 -fvisibility="hidden"               
                                                      
*/
```

Running both executables on this system outputs:
 
Testing (tcc version 0.9.27 (x86_64 Linux)) compiler
without attribute got 1
with    attribute got 1

Testing (gcc (GCC) 7.3.0) compiler
without attribute got 0
with    attribute got 1

Based on the semantics provided by the documentation, when the hidden flag
has been set, all the declared symbols in the compilation unit should be
hidden from outside that unit.

so for protection this should be coded unconditionally, like:
  
  __attribute__((visibility)("default"))) int Test;
 
as this (seems) to be the only way to get it right, even in the case when the
-fvisibility="hidden" flag hasn't been set.
 
But see also when the same variable is declared like (again when the hidden flag
has been set);

  extern int Test;

this breaks on gcc with this message:
   test.c:5: undefined reference to `Test'

Tcc compiles fine this code, but when it runs exits with:
  ./test-tcc: symbol lookup error: ./test-tcc: undefined symbol: Test

I guess there is a sort of confusion in these matters, especially for novices
when first meet C, and probably this comes from the lack of the namespace
concept, or because in C the default should be the opposite imho, and i simple
mean with that, that if there is a lesson that learned from all those years of
programming evolution, is that by default, symbols should be declared private to
the compilation unit, unless explicitly declared global to avoid collisions and
of course for efficiency reasons.
I guess that is what -fvisibility="hidden" does.

Best,
  Αγαθοκλής

Attachment: test.tar.bz2
Description: BZip2 compressed data


reply via email to

[Prev in Thread] Current Thread [Next in Thread]