Здравствуйте,
Помогите понять, почему компилятор допускает обе формы записи и какая из них, или обе, правильна.
class A
{
};
struct B: public A
{
};
struct C: public A
{
int a;
int b;
};
int main()
{
A* a = (sizeof(B)> sizeof(C)? (A*)new B: new C);
((C*)a)->b = 83;
return 0;
}
Если не указывать (A*) перед new B или перед new C, то GCC ругается:
test.cc: In function ‘int main()’:
test.cc:18:57: error: conditional expression between distinct pointer types ‘B*’ and ‘C*’ lacks a cast
Почему допускается форма записи приведенная выше, а не
A* a = (sizeof(B)> sizeof(C)? (A*)new B: (A*)new C);
Есть ли какая-то разница?
-------------------------
Сергей Ч.
Нижний Новгород
Здравствуйте, cse, Вы писали:
cse>Здравствуйте, cse> Помогите понять, почему компилятор допускает обе формы записи и какая из них, или обе, правильна.
Обе правильны.
Читай [expr.cond] в Стандарте. Там описаны ограничения на типы в условном операторе.
Здравствуйте, jazzer, Вы писали:
J>Здравствуйте, cse, Вы писали:
cse>>Здравствуйте, cse>> Помогите понять, почему компилятор допускает обе формы записи и какая из них, или обе, правильна. J>Обе правильны. J>Читай [expr.cond] в Стандарте. Там описаны ограничения на типы в условном операторе.
Только он не условный, а тернарный оператор (если быть занудным буквоедом). И там да, есть ньюанс с приведением типов.
Здравствуйте, Mr.Delphist, Вы писали:
J>>Читай [expr.cond] в Стандарте. Там описаны ограничения на типы в условном операторе.
MD>Только он не условный, а тернарный оператор (если быть занудным буквоедом). И там да, есть ньюанс с приведением типов.
Открой стандарт и удивись
ЗЫ Может, в Дельфи он так и называется, конечно... Но в С++ это 5.16 Conditional operator
Здравствуйте, jazzer, Вы писали:
J>Здравствуйте, uzhas, Вы писали:
U>>Здравствуйте, jazzer, Вы писали:
J>>>Открой стандарт и удивись
U>>вы оба правы: оператор и тернарный и условный
J>Он же буквоедствовать хотел, не мешай ему! Он ищет в Стандарте слово "ternary"
Теперь я знаю, что надо добавить в следующий Стандарт... И куда только Страуструп смотрит...
Здравствуйте, Лазар Бешкенадзе, Вы писали:
J>>>Обе правильны.
N>>Если не считать С-каста
ЛБ>Почему улыбаемся?
Спустя 4 года не смогу ответить.
ЛБ>Что не так с кастом?
Небезопасно.
Здравствуйте, Лазар Бешкенадзе, Вы писали:
ЛБ>>>Что не так с кастом? N>>Небезопасно.
ЛБ>Во-первых утверждение которое ты комментировал говорило о правильности а не безопасности.
Небезопасно == неправильно.
ЛБ>Во-вторых небезопасно иметь проститутку без презерватива а этот каст абсолютно безопасен.
Первая часть утверждения некорректна, наличие презерватива особенно не влияет на безопасность процедуры (если говорить о здоровье клиента). Вторая часть корректна только в условиях данного синтетического примера, а при реальной организации классов таким образом код становится небезопасным — т.к. небольшой рефакторинг легко превращает этот каст в мину.
Здравствуйте, Лазар Бешкенадзе, Вы писали:
ЛБ>Почему улыбаемся? Что не так с кастом?
То что он легко может превратиться в reinterpret_cast в случае несовместимых типов. К примеру, если A перестанет быть базовым классом.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Здравствуйте, Vain, Вы писали:
ЛБ>>Почему улыбаемся? Что не так с кастом?
V>То что он легко может превратиться в reinterpret_cast в случае несовместимых типов. К примеру, если A перестанет быть базовым классом.
Отсюда не следует что текст "неправильный".
Более того в таком случае требуется глубокая ревизия всех текстов и надежды на то что на все проблемы укажет компилятор только развращают.
Но я уже получил ответ на свой вопрос три дня назад и можно было не повторяться.