Выходное различие в gcc и Turbo C

Почему там различие в выводе, произведенном, когда код компилируется с помощью этих двух компиляторов gcc и turbo c.

#include <stdio.h>

int main()
{    
    char *p = "I am a string";
    char *q = "I am a string";

    if(p==q)
    {
        printf("Optimized");
    }
    else{
        printf("Change your compiler");
    }
    return 0;
}

Я добираюсь "Optimized" на gcc и "Change your compiler" на turbo c. Почему?

14
задан Prasoon Saurav 11 August 2010 в 02:25
поделиться

7 ответов

Ваш вопрос был помечен как C, так и C++. Поэтому я бы ответил для обоих языков.

[C]

Из ISO C99 (Раздел 6.4.5/6)

Не уточняется, являются ли эти массивы различными, если их элементы имеют соответствующие значения.

Это означает, что не определено, указывают ли p и q на один и тот же строковый литерал или нет. В случае gcc они оба указывают на "I am a string" (gcc оптимизирует ваш код), тогда как в turbo c это не так.

Неспецифическое поведение (Unspecified Behavior): Использование неопределенного значения или другое поведение, когда настоящий международный стандарт предоставляет две или более возможности и не предъявляет никаких дополнительных требований к тому, какая из них будет выбрана в каком-либо instance


[C++]

Из ISO C++-98 (Раздел 2.13.4/2)

Являются ли все строковые литералы различными (то есть, хранятся в непересекающихся объектах), определяется реализацией.

В C++ ваш код вызывает поведение, определяемое реализацией.

Implementation-defined Behavior: Неспецифическое поведение, где каждая реализация документирует, как был сделан выбор


Также смотрите этот вопрос.

33
ответ дан 1 December 2019 в 05:54
поделиться

Поскольку ваш строковый литерал является константным выражением, т.е. вы не должны изменять его через указатель, нет никакого реального смысла хранить его в пространстве памяти дважды. Будучи более новым компилятором, gcc по умолчанию объединяет литералы, в то время как Turbo C этого не делает. Это признак того, что gcc поддерживает более новый стандарт языка, в котором есть понятие const данных.

15
ответ дан 1 December 2019 в 05:54
поделиться

Turbo C был оптимизирован для быстрой компиляции, поэтому у него нет никаких особенностей, которые могли бы замедлить его работу. Распознавание дубликатов строк было бы замедлением, пусть даже незначительным.

3
ответ дан 1 December 2019 в 05:54
поделиться

Пожалуйста, забудьте ответы в той же строке, что и

"Это потому, что Turbo C ТАК СОВЕРШЕННО СТАРЫЙ, и они не могли сделать это ТОГДА, потому что это должно было быть БЫСТРО, но GCC совершенно НОВЫЙ и RAD, и поэтому он делает это!".

Оба компилятора поддерживают объединение строковых констант в качестве опции. Опция GCC (-fmerge-constants) включается на уровнях оптимизации, а опция Turbo C (-d) по умолчанию выключена. Если вы используете TCC IDE, то зайдите в Options|Compiler...|Code Generation... и отметьте пункт "Duplicate strings merged".

10
ответ дан 1 December 2019 в 05:54
поделиться

На странице руководства gcc:

-fmerge-constants

Попытка объединить идентичные константы (строковые константы и константы с плавающей запятой) через единицы компиляции.

Этот параметр используется по умолчанию для оптимизированной компиляции, если ассемблер и компоновщик поддерживают это. Использовать -fno-merge-constants, чтобы запретить такое поведение.

Включено на уровнях -O, -O2, -O3, -Os.

Отсюда вывод.

5
ответ дан 1 December 2019 в 05:54
поделиться

Компилятор может хранить две копии одинаковых литералов, если посчитает нужным. Выяснить, так ли это, предположительно и является целью данной программы.

В старые добрые времена ассемблеры хранили все литералы в пуле литералов, и исправление пула литералов было признанной (если не одобренной) техникой изменения "констант" во всей программе.

Если по какой-то случайности компилятор разрешит в этом случае *p = 'H'; то возникнут важные различия в поведении.

1
ответ дан 1 December 2019 в 05:54
поделиться

Историческая сноска: поскольку адреса были меньше числовых констант с плавающей запятой, FORTRAN использовался для обработки констант с плавающей запятой так же, как C обрабатывает строки. Поскольку память была драгоценна, идентичным константам будет выделяться одно и то же пространство. Кроме того, передача параметров всегда выполнялась по ссылке. Это означало, что если передать числовую константу процедуре, которая изменила свой аргумент, другие вхождения этой «константы» изменили бы значение.

Отсюда старая поговорка: «Переменные - нет, константы - нет».

Между прочим, кто-нибудь заметил ошибку в printf Turbo C 2.0, которая не позволяла использовать формат типа "% 1.1f" для печатать числа вроде 99.99 (выводит 00.0)? Исправлено в версии 2.01, это напоминает мне ошибку калькулятора Windows 3.1.

0
ответ дан 1 December 2019 в 05:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: