const в C против const в C

#c #c #constants

#c #c #константы

Вопрос:

Данный код компилируется на C, но завершается ошибкой на C .

 int main()
{
   const int x; /* uninitialized const compiles in C but fails in C  */
}
  

В чем обоснование и причина перехода с C на C ?

Ответ №1:

Смотрите спецификацию в приложении по совместимости C.1.6:

7.1.6 [см. также 3.5]

Изменение: объекты const должны быть инициализированы на C , но могут быть оставлены неинициализированными на C

Обоснование: объекту const нельзя присвоить значение, поэтому он должен быть инициализирован для хранения полезного значения.

Влияние на исходную функцию: удаление семантически четко определенной функции.

Сложность преобразования: семантическое преобразование.

Насколько широко используется: Редко.

Комментарии:

1. Объекту const может быть присвоен в C?

2. @Sergii Я так не думаю. И только определения области действия файла могут быть предварительными в C. Так что, я думаю, у программы на C не было бы способа предоставить значение для const переменной области действия блока.

3. @JohannesSchaub-программа на C (или C ) litb может предоставить значение для переменной const с помощью приведения: const int i; *((int*)amp;

4. @Yuri Это невозможно. Это неопределенное поведение.

Ответ №2:

Обратите внимание, что существует законное использование неинициализированного объекта с определением const и длительностью автоматического хранения: его адрес может быть взят и использован в качестве уникального ключа для обозначения уровней рекурсии в рекурсивной функции. Это несколько неясно, но стоит отметить. C делает это использование эффективным, в то время как C требует, чтобы вы тратили время и размер кода на его инициализацию. (Теоретически компилятор, возможно, мог бы определить, что значение никогда не используется, и оптимизировать инициализацию, но поскольку вы передаете указатель, это было бы довольно сложно доказать.)

Комментарии:

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

2. Если у него есть автоматическое хранилище, компоновщик никак не сможет его внедрить; для каждого вызова функции существует один экземпляр, а не что-то глобальное. И как только на уровне исходного кода появляется UB (из-за доступа к неопределенному значению неинициализированного объекта), компилятор, возможно, уже сгенерировал случайный бессмысленный код еще до того, как компоновщик его увидит.

3. Это правда, я не смог увидеть «автоматический».

Ответ №3:

const Ключевое слово было введено в C в C89 в 1989 году, но было с C с момента его создания в 1983 году. Итак, он был «перенесен» с C на C.

Семантика инициализации обычно отличается в C и C . Хотя большую часть времени они «просто делают то, что вы ожидаете», бывают случаи, когда различия становятся довольно важными. В конце концов, C на самом деле не является надмножеством C.

Например, в C вы не можете:

 goto x;
int i = 3;
x:
puts("Hello, world");
  

Но это совершенно законно в C.

Комментарии:

1. Не собираюсь понижать голос, поскольку это интересно (и правильно), но это не совсем отвечает на вопрос.

Ответ №4:

Стандарт ISO гласит (в 8.5 [dcl.init], параграф 9):

Если для объекта не указан инициализатор, и объект имеет (возможно, cv-квалифицированный) тип класса, отличный от POD (или его массива), объект должен быть инициализирован по умолчанию; если объект имеет const-квалифицированный тип, тип базового класса должен иметь объявленный пользователем конструктор по умолчанию.

если вы попробуете тот же пример после изменения этого:

 int main()
{
   /*Unless explicitly declared extern, a const object does not have
 external linkage and must be initialized*/
   extern const int x; 
   return 0;
}
  

он будет скомпилирован. Итак, этот self объясняет необходимость принудительного применения этой ошибки к c , объявление переменных const без инициализации и привязки extern бесполезно, поэтому кодер, должно быть, добавил его по ошибке.

Ответ №5:

 #include<iostream>
using namespace std;

class Test
{
    int value;
    public:
        Test(int v = 0) {value = v;}
        int getvalue() const {return value;}
};

int main(){

    Test t(20);
    cout << t.getvalue();
    return 0;
     
    const double P1 = 68.68;
    cout<<P1<<endl;
    
    int star  = 57;
    int const *pstar = amp;star;
    cout<<*pstar<<endl;
    
    return 0;
    
}
  

Комментарии:

1. Как это объясняет разницу между C и C ?