user6083108
user6083108

Reputation: 31

GCC weak attribute on constant variables

I have a question regarding weak attribute of const variable. I have the following couple of files compiled with gcc:

main.c:

#include <stdio.h>

const int my_var __attribute__((weak)) = 100;

int
main(int argc, char *argv[])
{
  printf("my_var = %d\n", my_var);
}

other.c:

const int my_var = 200;

When I compile these two files and run the application I get the following result:

my_var = 100

Since I'm using weak attribute on the my_var variable in main.c I thought it should be overridden by my_var variable in other.c, but that wasn't the case...

Now if I drop the const keyword of my_var in main.c:

#include <stdio.h>
/* Dropping const... */
int my_var __attribute__((weak)) = 100;

int
main(int argc, char *argv[])
{
  printf("my_var = %d\n", my_var);
}

Then re-compile, I get the desired result:

my_var = 200

Which is what I expect.

Note: If I drop the const in the file other.c I still get the result of 200.

My question is: why using const keyword changes the behaviour of weak attribute? Is it related to which section the variable resides in?

The Makefile I'm using is:

.PHONY: all clean

TARGET=test
OBJS=main.o other.o

all: $(TARGET)

$(TARGET): $(OBJS)
    gcc $(OBJS) -o $(TARGET)

main.o:main.c
    gcc -c main.c

other.o:other.c
    gcc -c other.c

clean:
    rm -rf *.o $(TARGET)

Thanks in advance,

Upvotes: 3

Views: 4527

Answers (2)

Lrnt Gr
Lrnt Gr

Reputation: 379

I faced the same issue (cf. GCC optimization bug on weak const variable) and came up with the conclusion that gcc does not handle well the optimization on the weak/const variable within the file where the weak definition is: in your 'main.c' file, my_var is always resolved to 100.
Not sure, but it seems to be a gcc bug (?).

To solve this, you can :

  • prevent optimization, by adding the -O0 option to gcc.
    • -O0 should be the default value, so this might not help...
  • get rid of the const keyword as you did: gcc cannot optimize no more as my_var can potentially change now.
  • set your const int my_var __attribute__((weak)) = 100; statement in a separate source file ('main_weak.c' for instance): while building 'main.c', gcc does not know the my_var value and thus won't optimize.

Upvotes: 1

too honest for this site
too honest for this site

Reputation: 12263

The identifiers have internal linkage. This is an obsolecense feature (static storage class specifier should be used). In general, you should have a header with an extern declaration of the identifier:

extern const int my_var;

Linking with different qualifiers is a bad idea.

Maybe the better understandable approach is to use wekref plus alias.

Upvotes: 0

Related Questions