#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 ?