Вызывает ли доступ к сегменту .text через внешние переменные поведение undefined?

Это файл "1.c"

    #include <stdio.h>
    char foo;
    int bar(){
    }
    int main(){
        printf("%d",foo);
        return 0;
    }
    //--------------------------

Это файл '2.c'

    void foo(){
    }

Компилятор вызывается как gcc 1.c 2.c

Вышеизложенное дает неопределенное поведение? Думаю, да. В противном случае сделать оптимизацию практически невозможно.

Несколько разных определений для одного и того же объекта (класс, шаблон, перечисление, встроенная функция, статическая функция-член и т. д.) [Какие все общие неопределенные поведения должны знать программисту C++?

Но, насколько мне известно, char foo создает только слабый символ, который может быть переопределен с помощью void foo(){} при связывании. Более того, если я заменю char foo на extern char foo, останется ли это определение?


person phoeagon    schedule 08.04.2013    source источник
comment
Обсуждение таких вещей, как слабые символы, выходит за рамки стандарта C (и поэтому не обязательно имеет смысл спрашивать, применимо ли здесь неопределенное поведение)...   -  person Oliver Charlesworth    schedule 09.04.2013
comment
extern char foo будет только объявлением, а не определением. Вы можете попробовать добавить его в 1.c (без 2.c), он должен выдавать ошибку при компиляции   -  person Marc Simon    schedule 09.04.2013
comment
Я думаю, вы можете получить ответ от stackoverflow.com/questions/2766022/   -  person MYMNeo    schedule 09.04.2013


Ответы (1)


Это вызовет неопределенное поведение, да. Вероятно, есть много цитат из стандарта, которые являются явными для различных типов объявлений и т. д., но это подводит итог:

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

Все объявления, относящиеся к одному и тому же объекту или функции, должны иметь совместимый тип; в противном случае поведение неопределенно. (6.2.7)

char foo; в вашем примере является предварительным определением. Если вы используете extern, это будет не определение, а объявление, и вышеприведенное все равно будет применяться.

person teppic    schedule 09.04.2013