Здравствуйте, klizardin, Вы писали:
K>Смею разочаровать получи весь листинг твоего кода и окажется, что ты где-то написал #define bool int
Что за чушь? В этом случае typeid выдаст int.
Здравствуйте, anonim_44ax, Вы писали:
_>Случайно написал: _>
_>signed bool test = -true; ///< MS VS watch кстати говорит, что test имеет тип int :xz:
_>
_>И заработало _>Народ, почему это заработало? Зачем вообще в С++ signed/unsigned для bool?
Эхх.. конечно же если выключать варнинги а также ставить минимальный уровень предупреждения от компилятора то ждут таких программеров открытия. при этом открытие того, что компилятор скомпилировал signed и проигнорировал дальнейший bool стало конечно же открытием, но будут и куда как более "приятные" открытия если отключать варниги.
читаем msdn.
Compiler Warning (level 1) C4076
Error Message
'typemod' : can not be used with type 'typename'
A type modifier, whether it is signed or unsigned, cannot be used with a noninteger type. typemod is ignored.
Здравствуйте, klizardin, Вы писали:
K>Эхх.. конечно же если выключать варнинги а также ставить минимальный уровень предупреждения от компилятора то ждут таких программеров открытия. при этом открытие того, что компилятор скомпилировал signed и проигнорировал дальнейший bool стало конечно же открытием, но будут и куда как более "приятные" открытия если отключать варниги.
Добрый MS-компилятор, который только погрозит пальчиком на, например, такое:
Здравствуйте, dmitry_npi, Вы писали:
d_n>Ведь signed void() — это вызов конструктора типа signed void
По стандарту этот код вообще незаконен. Выражение int() — это преобразование типа в функциональной нотации, где нет вызова какого-либо конструктора (int — встроенный тип, и у него нет конструктора).
d_n>то есть это выражение, но не декларация функции.
В коде
std::cout << typeid(int()).name() << std::endl;
int() — это не выражение и не объявление функции. Это тип (type-id) "функция без параметров, возвращающая int". Операндом typeid может быть как выражение, так и тип (см. 5.2.8). С другой стороны, int() может рассматриваться как выражение и как тип. Разрешение неоднозначности происходит согласно 8.2/2:
The ambiguity arising from the similarity between a function-style cast and a type-id can occur in different contexts. The ambiguity appears as a choice between a function-style cast expression and a declaration of a type. The resolution is that any construct that could possibly be a type-id in its syntactic context shall be considered a type-id.
т.е. в пользу интерпретации конструкции int() как типа, а не выражения.
Здравствуйте, anonim_44ax, Вы писали:
_>Случайно написал: _>
_>signed bool test = -true; ///< MS VS watch кстати говорит, что test имеет тип int :xz:
_>
_>И заработало _>Народ, почему это заработало? Зачем вообще в С++ signed/unsigned для bool?
signed unsigned определяют какие asm-овские команды использовать в арифметических выражениях. предполагаю мелкомягкие просто сделали это момент варнингом изначально по крайней мере найденной шестой студии этот варнинг присутствует, а потом не стали менять. это в большей степени связано с тем, что вообще-то и мелкомягкие частенько создавали версии до фиксации стандарта и поэтому просто уже не переписывали варнинги на ошибки из-за того, что уже так было принято. более чем нормальная ситуация.
Здравствуйте, ned, Вы писали:
ned>Добрый MS-компилятор, который только погрозит пальчиком на, например, такое: ned>
signed double float void bool int long b;
еще раз причины могли быть просто банальны: нужно было сохранить обратную совместимость. причин большое количество.
и это еще раз доказывает, что варнинги в MSVC более чем важны. просто для кучи оболтусов (хотя все программисты в той или иной степени такие), которые демонстрируют отношение что-то вроде: "программа работоспособна, если она откомпилировалась".
K>Смею разочаровать получи весь листинг твоего кода и окажется, что ты где-то написал #define bool int
Вы прежде чем нравоучения мутить, скомпилировали бы, а.
Указанный пример production кодом не является. Не беспокойтесь о нашем проекте, также можете попридержать нравоучения в стиле: "так писать плохо". Я и думаю все остальные вкурсе, что использовать этот "трик" нельзя, Капитан Очевидность. Прикол-то не в этом.
Здравствуйте, anonim_44ax, Вы писали:
_>Знает кто-нибудь нафига в С++ такие недо-типы? Это же еще хуже char, signed char, unsigned char. Если я верно понял, то signed и unsigned bool это typedef-ы соответственно:
Нет, это встроенные типы. Причем компилятор, который их понимает (любой C++ компилятор, и компилятор, понимающий C99) кладет туда только 0 и 1. Т.е. bool i = 5; положит в i единицу, а не 5.
Здравствуйте, anonim_44ax, Вы писали:
_>Специально для "танкистов" и klizardin уточняю.
_>Указанный пример production кодом не является. Не беспокойтесь о нашем проекте, также можете попридержать нравоучения в стиле: "так писать плохо". Я и думаю все остальные в курсе, что использовать этот "трик" нельзя, Капитан Очевидность. Прикол-то не в этом.
А в чем? В том, чтобы еще раз сказать бяки-буки мелкомягкие, они же не сделали эту ситуацию ошибкой, а сделали варнингом. Какие ужасные мелкомягкие! Это что-ли?
И даже не с точки зрения того, что "ведь все же мы делаем ошибки", а с точки зрения, что механизм предусмотрен сообщения об ошибке, а существование такого сообщения вполне может объясняться исторически. Или же что, мелкмягкие не вскрыли мозги всем программистам ради signed bool и не сделали ("как правильно") это ошибкой в некоторой новой версии? это что-ли?
В чем прикол?
это вообще не портируемая фича/баг и люди, которые вообще-то пишут хороший код, просто не будут использовать этот момент (потому что себе дороже да и не соответствует стандарту). или вы уверены, что все компиляторы написаны одной рукой и все они идентичны и только компилировались на разных языках и только из-за последнего и существуют и intel-овский компилятор и MSVC и тот же gcc. Каждый компилятор имеет свои особенности. Поэтому обычно для определения потенциальной портируемости библиотеки обычно есть тестовые куски кода, просто для проверки может ли язык(в данном случае C++) обрабатывать (и делать это корректно) определенные языковые конструкции. И естественно, есть свои нюансы у каждого из компиляторов.
***
Ну и если нужны морали)
Я не говорю, что так писать плохо. Плохо отключать варнинги и быть уверенным, что "ну это же только варнинги". И плохо поминать всуе мелкомягких (так как это же самое главное зло на планете) говоря, что ну вот они "реализовали" баг.
***
Вообще-то забавная фича, но фактически-то мне как программисту, что она дает? У MSVC были и куда веселее фичи.
_>Сломал мозг пока пытался себе представить "знаковое и беззнаковое ничто" _>Хотя вроде "правда с минусом" звучит более-менее логично (и значит пожалуй "неправда") {
Ха! А я вот подумал что правда с минусом, это всё-таки правда, но с очень плохими последствиями
Здравствуйте, TarasKo, Вы писали: _> return signed void(); TK>Ха! А я вот подумал что правда с минусом, это всё-таки правда, но с очень плохими последствиями
это все по просьбе Андриеску сделано, чтоб void функции удобней биндить
Здравствуйте, Masterkent, Вы писали:
M>По стандарту этот код вообще незаконен. Выражение int() — это преобразование типа в функциональной нотации, где нет вызова какого-либо конструктора (int — встроенный тип, и у него нет конструктора).
Ещё у Страуструпа, кажется, об этом есть, но нашёл не в нём, а в "Шаблонах С++" Вандевурда и Джосаттиса. Часто нужно делать вещи типа
T x = T();
и не думать, встроенный ли это тип.
По этой причине для встроенных типов можно явно вызывать стандартный конструктор, который инициализирует их нулём (или значением false для bool), т.е. int() даёт нуль.
Но здесь всегда требуется статья с пунктом... Вот нашёл, кажется (5.2.3/2):
The expression T(), where T is a simple-type-specifier (7.1.5.2) for a non-array complete object type or
the (possibly cv-qualified) void type, creates an rvalue of the specified type, whose value is determined by
default-initialization (8.5; no initialization is done for the void() case). [Note: if T is a non-class type
that is cv-qualified, the cv-qualifiers are ignored when determining the type of the resulting rvalue (3.10).]
По этой причине для встроенных типов можно явно вызывать стандартный конструктор, который инициализирует их нулём (или значением false для bool), т.е. int() даёт нуль.
Это выдумки, стандарт не связывает инициализацию скалярного объекта нулевым значением с вызовом какого-либо конструктора. Более того, даже если T — классовый тип, то в общем случае нельзя сказать, что выражение T() создаёт объект именно с помощью конструктора. В частности, конструктор по умолчанию никогда не вызывается для создания объектов POD-классов.
K>Но здесь всегда требуется статья с пунктом... Вот нашёл, кажется (5.2.3/2): K>
The expression T(), where T is a simple-type-specifier (7.1.5.2) for a non-array complete object type or
the (possibly cv-qualified) void type, creates an rvalue of the specified type, whose value is determined by
default-initialization (8.5; no initialization is done for the void() case). [Note: if T is a non-class type
that is cv-qualified, the cv-qualifiers are ignored when determining the type of the resulting rvalue (3.10).]
Я не вижу тут упоминания о конструкторе. И, кстати, это цитата из отменённого стандарта '98-го года. Действующим стандартом на данный момент является ISO/IEC 14882:2003(E) aka C++03.
По этой причине для встроенных типов можно явно вызывать стандартный конструктор, который инициализирует их нулём (или значением false для bool), т.е. int() даёт нуль.
M>Это выдумки, стандарт не связывает инициализацию скалярного объекта нулевым значением с вызовом какого-либо конструктора.
И кому из вас (непосредственно вам или книжке) верить?..
M> И, кстати, это цитата из отменённого стандарта '98-го года. Действующим стандартом на данный момент является ISO/IEC 14882:2003(E) aka C++03.
Разве что считать книгу устаревшей...
M> Более того, даже если T — классовый тип, то в общем случае нельзя сказать, что выражение T() создаёт объект именно с помощью конструктора. В частности, конструктор по умолчанию никогда не вызывается для создания объектов POD-классов. M> Я не вижу тут упоминания о конструкторе.
Да и не говорю ничего о конструкторе. Я хотел выяснить, почему void() и int() невалидны в качестве выражения.