Так чистых С-компиляторов практически нет природе. Внутри всех более-менее распространённых компиляторов (gcc, clang, ms, intel и др) С реализован как подмножество С++ с незначительными расширениями. => сразу возникает вопрос как оно должно будет компилироваться в соответствии со стандартами надмножества с опцией -ansi Тем более, что на практике компилить С внутри плюсов иногда приходится.
я узнал не просто новое, а нечто противоречащее известным мне ранее сведениям, потому и хочу разобраться насколько ранее известные мне сведения были ошибочны
то что, насколько мне было ранее известно (возможно сведения ложные, как минимум, в случае С это уже оказалось неверно), в машинного представлении bool может хранить false в виде 0, а true в виде произвольного ненулевого числа => компилятор имеет право оптимизировать выражение (= !!x) вплоть до простого (= x)
про это давно, когда я ещё учился, говорил препод в универе, поэтому я до сих пор считал это утверждение истинным, а оно эвон как
Компилятор действует так, как прописано в спецификации языка.
Заметь.
Не так, как препод в школе говорил.
Не так, как «машинное представление».
Не так, как «внутри всех более-менее распространённых компиляторов» чего-то сделано.
А так, как прописано в референсном документе.
Вот если в референсном документе оставлено место для творчества, тогда разработчик может выразиться по своему усмотрению.
компилятор имеет право оптимизировать выражение (= !!x) вплоть до простого (= x)
Различай «компилятор имеет право оптимизировать в частном случае с сохранением семантики» и «компилятор имеет право оптимизировать как бог на душу положит».
В условии if (!!a) можно смело выкидывать лишние логические операции, потому что для if-а любой не-ноль — истина.
А в коде int f(int a) {return !!a;} выкидывание операций приведёт к изменению семантики.
Не так. Автомобили toyota и lexus - собираются на одном и том же заводе из одних и тех же деталей, просто у лексуса «плюшек» и => деталей поболее. Поэтому лексус - это расширенная тойота.
//Сравнение недостаточно полное, т.к. всё же у лексуса, в зависимости от модели, значительная часть деталей не соотв. таковым у простых тойот
который используется в соответствии с бумажкой, описывающей стандартизированное поведение
Ну да, только к чему это ты? Это не отменяет и не противоречит тому, что clang и gcc реализуют поддержку С как подмножества С++, что логично и практично, ну или поддержку С++ как надмножество С, как кому приятней.
Я к тому, что исходное утверждение next_time-а лишено логического содержания. Из того, что «Так чистых С-компиляторов практически нет природе» никак не следует, что эти «грязные компиляторы» не должны следовать референсному документу. Если в мане написано, что компилятор реализует C11, значит семантика программ обрабатывается в соответствии с бумажкой ISO/IEC 9899:2011. А сделано это единым блоком с C++ или интерпретатором на ку-васике — не имеет значения.
К сожалению, практика показывает, что это не так. На практике, как минимум, clang и gcc в некоторых отдельных случаях нельзя заставить строго соотв. ни стандарту С, ни стандарту С++ даже с флагом -ansi. Они всё равно компилируют сборную солянку из С и С++. Причём как в случае попытки компиляции С-шки, так и С++. Это из того, на что я натыкался уже на практике.
Ой да лана. Именно разработка и обкатка конструкций в C++ и привели к бурному развитию Си-шки, который до C++ был весьма консервативен до окаменения. Но по сути это и было протискивание фич из C++ в C за счёт поддержки их в сишке, по принципу - не противоверчит синтаксису и не превращает его в другой язык. Деклалирование в любом месте переменных, начиная с декларации функции и заканчивая в for, анонимные структуры и так далее в классической Сишке натуральное досадное ограничение языка, которое было объяснимо при рождении языка на 64kБ хватит всем и совершенно архаично смотрящееся сейчас. А вот комментарии '//' уже спорное дополнение.
но это сишная фича, не должна она компилиться вообще
Это не «сишная фича», а гнутое расширение крестов. А если бы ты с использованием __int128 программу написал, тоже на «сишные фичи» бы списал это? Или гнутые аттрибуты функций?
компилируется с опцией -ansi, хотя и выдаёт варнинг
Потому что ты компилируешь не «C++», а «C++ с гнутыми расширениями». Чтобы компилировать максимально близко к стандарту, надо использовать режим pedantic:
vadim@aquila:/tmp$ g++ -c -std=c++11 -pedantic-errors -Wall 1.cpp
1.cpp: В функции «void f()»:
1.cpp:5:12: ошибка: ISO C++ запрещает массив переменного размера «x» [-Wvla]
int x[z];
^
Потому что ты компилируешь не «C++», а «C++ с гнутыми расширениями».
гнутые расширения по-дефолту - уже «чудесно»
«Чтобы компилировать максимально близко к стандарту, надо использовать режим pedantic»
Авторы gcc считают иначе:
Give an error whenever the base standard (see -Wpedantic) requires a diagnostic, in some cases where there is undefined behavior at compile-time and in some other cases that do not prevent compilation of programs that are valid according to the standard.
...которые появились в gcc задолго до принятия С99.
гнутые расширения по-дефолту - уже «чудесно»
Да, если читать документацию, можно еще много открытий сделать.
Авторы gcc считают иначе:
The original ISO C++ standard was published as the ISO standard
(ISO/IEC 14882:1998) and amended by a Technical Corrigenda published in
2003 (ISO/IEC 14882:2003). These standards are referred to as C++98 and
C++03, respectively. GCC implements the majority of C++98 ('export' is
a notable exception) and most of the changes in C++03. To select this
standard in GCC, use one of the options '-ansi', '-std=c++98', or
'-std=c++03'; to obtain all the diagnostics required by the standard,
you should also specify '-pedantic' (or '-pedantic-errors' if you want
them to be errors rather than warnings).