Слабый атрибут GCC при объявлении переменной

В GCC, если переменная объявлена ​​с атрибутом weak и во время (статической) компоновки определение не найдено, переменная будет иметь адрес ноль, т. е. если указатель инициализируется адресом переменной, указатель будет NULL, как показано в следующих фрагментах кода:

foobar.c:

extern int foo __attribute__((weak));
extern int bar;

int *a[] = {&foo, &bar};

main.c:

#include <diag/Trace.h>

//int foo;
int bar;
extern int *a[];

int main(void) {
    trace_printf("%p, %p", a[0], a[1]);
    return 0;
}

Результат: 0, 0x20000120 (я использую arm-none-eabi-gcc 5.4.1)

Вопрос в следующем: хотя поведение ожидаемо, ни в одном документе об этом не упоминается. Может ли кто-нибудь указать мне на какой-либо материал, объясняющий такое поведение? Спасибо!


person dingcurie    schedule 23.11.2016    source источник


Ответы (1)


Я не думаю, что ожидал бы этого, я бы предположил, что GCC будет делать то же самое, как если бы слабый атрибут отсутствовал. Документация:

https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Common-Function-Attributes

... так что это выглядит как недокументированное/неопределенное поведение.

person James Antill    schedule 23.11.2016
comment
Но именно так GCC ведет себя на самом деле, так что можно сказать, что этого ожидают и авторы GCC. Это также реализовано в IAR, как прямо сказано в его руководстве: компоновщик не будет..., а отсутствие определения для слабой ссылки не приведет к ошибке. Если определение не включено, адрес объекта будет равен нулю. - person dingcurie; 25.11.2016
comment
Нет, если бы они ожидали, что это всегда будет делать это, они бы задокументировали это как это. Вот что значит недокументированный/неопределенный, он по-прежнему что-то делает, и это может быть полезно для вас... но может не всегда делать это. - person James Antill; 19.12.2016