раскомментить любую из строк 17 или 19 в .ino, в setup()
IDE 1.8.9
Ну и, по традиции, "ПАМАГИТИ!!!!"
Подтверждаю проблему на 1.8.8.
И чего орать? Глюк компилятора впервые увидел шоле. Переписал бы код без выпендрежа лишнего та и делов, а терь жди кто про архатовщину на сайте напишет.
Лучше бы озаботился тем, что из-за бездумног IndexOf у тя стало 2 прохода по массиву. Искал бы по ходу в том цикле где печать так и одним обошелся.
ПС. Неделю назад втыкал. Так работает
switch(statusCool)
{
....
case 3: //первое достоверное значение датчика 0 (внутри)
TermObj = Termo1Val;
myOLED.drawString(0,3,"term2 ");
statusCool++;
return;
case 4:
TermAir = Termo1Val;
statusCool++;
break;
Оно конечно обявить переменную снаружи от свича наверно красивше будет чем в одном из кейсов как вышло в следствие копипаста. Ну так ладно бы не собиралось и ткнуло носом что здесь фигня. Так нет же, сука полупроводниковая, измывается над человеком!
Вопщем, нада на Паскаль переходить. Там 20-ти томов стандартов хоть и нету, но я в класс всё что угодно могу инкапсулировать. А тут придется прятать на уровне модулей (единиц компиляции). Дурдом, каоче, нада напица. Пойду я.
Вопщем, нада на Паскаль переходить. Там 20-ти томов стандартов хоть и нету, но я в класс всё что угодно могу инкапсулировать. А тут придется прятать на уровне модулей (единиц компиляции). Дурдом, каоче, нада напица. Пойду я.
2. полученный через констэкспр такой элемент класса, как видишь не становится настоящим. То есть компилятор пропускает, а линковщик дает ошибку. Это уже не АВР, это просто Линух и VSCode с GCC.
3. Все еще надеюсь на то, что Женя знает о стандарте больше меня, а так оно и есть, и найдет способ инициализации не интегральных статиков.
==================
У меня пока только такой вариант, может он тебя устроит. Под реалии Ардуины сам переделаешь, ежели чо.
причем в dadaLen нужно писать именно имя _someData - внешнего массива, а не someData. Иначе констэкпр считает неправильно.
Этот пример на принт из стр19. А самое загадочное - принт стр17.
без этой строки компилятор создает код иначе. Пользуется данными этапа компиляции, в котором он нормально обработал все выражения и статики Дедова класса. А с ней - уже передает линковщику ссылки... которых в реале нет ;))))
---------
И да - это конечно глюк. Вот прям маслице для любителей поругать компилятор! ;))) Логик может плясать. У кого-то есть компилятор лучше?
Результат: в ардуине и в AVR-студии одинаковая ошибка, а в мелкомягком компиляторе и в билдере - всё компилируется на ура.
Вопрос-то всё равно остаётся - что провоцирует такое поведение? Я в этом пытаюсь разобраться. Понятно же, что деду не нужен совет "как сделать, чтобы работало" - это он и без нас отлично сделает. Ему любопытно "чё за хрень". Мне тоже.
То, что программист тут "выпендрился" в общем-то понятно, но компилятор должен был разобраться и либо оставить массив в памяти (наплевав на constexpr), либо развернуть цикл и уйти от переменной в индексе. Но он, похоже, черезчур увлёкся оптимизацией. Ладно, следствие продолжается.
а шож им дизасемблить если ниче не собралось. Почти уверен что мелкомягкий компилятор просто забил на оптимизацию, вот оно и прошло :) Иногда лучший подход к проблеме - забить хер. В данном случае забили оптимизировать.
Я не нашел, где бы в стандарте было РАЗРЕШЕНО инициализировать статик элементы неинтегрального (хотя по русски надо говорить "несчетного") типа. Если некоторые компиляторы это пропускают - здорово.
Плохо, что GCC на этапе компиляции не ругается, но и не создает массив в памяти. Это глюк. Надо о нём знать.
вот обход. Мне всегда только это интересно. Ошибки в софте, даже таком проверенном миллионами, как GCC - нормально.
Золотые слова! С этим фактом надо жить. И писать в обход глюков. И писать проще, оно так всем приятней, и компилятору и читателям. И не спешить лезть в С++17 и прочие тяжкие.
Вопрос-то всё равно остаётся - что провоцирует такое поведение? Я в этом пытаюсь разобраться. Понятно же, что деду не нужен совет "как сделать, чтобы работало" - это он и без нас отлично сделает. Ему любопытно "чё за хрень". Мне тоже.
Да. Я понять хочу, с тем ли канпилятором я связался. :-) итииемать.
Да. Я понять хочу, с тем ли канпилятором я связался. :-) итииемать.
Не, ну, ты сам то пиши правильно! Твой вопрос же не о прямой ошибке компилятора, а о неправильной реакции на ошибку программиста, разве не так? Если бы ты написал правильно, то и проблем бы не было. А так, ты, конечно прав, он должен был либо ругнуться, либо послать твой constexpr и разместить массив в памяти (может ещё предупреждение выдать). А он, сволочь, пропустил молча и подсунул свинью линкеру.
В стандарте прямо сказано (разд 12.2.3.2(3) на стр. 249): "If a non-volatile non-inline const static data member is of integral or enumeration type, its declaration in the class definition can specify a brace-or-equal-initializer in which every initializer-clause that is an assignment-expression is a constant expression. The member shall still be defined in a namespace scope if it is odr-used in the program and the namespace scope definition shall not contain an initializer".
Большинство компиляторов позволяют этого не делать (не размещать определение), GCC тоже позволяет, но, как показала практика, не всегда корректно.
Т.е. если мы напишем точно по стандарту (твой .h файл)
то GCC глючить не будет - я запускал со всеми раскомментированными строками - всё нормально пашет. А вот его реакция на нашу ошибку глюкавая.
Важное замечание: разумеется добавленное мною определение нужно не в .h файле размещать, а то плодиться начнёт.
Блин, целый день траха чтобы понять, что GCC, видя constexpr изо всех сил пытается не размещать его в памяти, а когда не получается, (А) не проверяет есть ли уже размещение и (Б) не размещает сам.
Спасибо ЕвгенийП за подробное объяснение, свою ошибку я понял. С++ дает инициализировать в описании только простенькие, "импотентские" типы. Другие инициализаторы надо пхать в cpp файл. Акей.
Стандарты не читал, но осуждаю, как Пастернака. :)
Про Эру расскажите. Интересно.
Обязательно, здесь же в отвлечённых в ближайшие день-два
Про Эру расскажите. Интересно.
конечно интересно, что еще кроме строевой )))
раскомментить любую из строк 17 или 19 в .ino, в setup()
IDE 1.8.9
Ну и, по традиции, "ПАМАГИТИ!!!!"
Подтверждаю проблему на 1.8.8.
И чего орать? Глюк компилятора впервые увидел шоле. Переписал бы код без выпендрежа лишнего та и делов, а терь жди кто про архатовщину на сайте напишет.
Лучше бы озаботился тем, что из-за бездумног IndexOf у тя стало 2 прохода по массиву. Искал бы по ходу в том цикле где печать так и одним обошелся.
ПС. Неделю назад втыкал. Так работает
И так работает
А так в case 4 и все следующие не заходит. Хотя statusCool равен 4, зуб даю! я его и на экран и в сириал!
8))
А вот так снова работает
Оно конечно обявить переменную снаружи от свича наверно красивше будет чем в одном из кейсов как вышло в следствие копипаста. Ну так ладно бы не собиралось и ткнуло носом что здесь фигня. Так нет же, сука полупроводниковая, измывается над человеком!
и ворнингов нету?
Вопщем, нада на Паскаль переходить. Там 20-ти томов стандартов хоть и нету, но я в класс всё что угодно могу инкапсулировать. А тут придется прятать на уровне модулей (единиц компиляции). Дурдом, каоче, нада напица. Пойду я.
и ворнингов нету?
Нету нихрена. Токо шо включил спецом "Все". Даже так нету.
ПС. Но польза есть, странный
SSD1306.cpp:156:5: warning: 'r' may be used uninitialized in this function [-Wmaybe-uninitialized] for (;r;r--)
в моей же либе оказывается!
Вопщем, нада на Паскаль переходить. Там 20-ти томов стандартов хоть и нету, но я в класс всё что угодно могу инкапсулировать. А тут придется прятать на уровне модулей (единиц компиляции). Дурдом, каоче, нада напица. Пойду я.
кто не может паскалить тот будет сикать?
А тут придется прятать на уровне модулей (единиц компиляции).
так и нормально. А вобще от кого прячем? ;) И шо удастся? А если найду ;)
Дед! Пока Женя думает вот самый короткий пример:
теперь комментарии:
1. как видишь я добавил gnu++17.
2. полученный через констэкспр такой элемент класса, как видишь не становится настоящим. То есть компилятор пропускает, а линковщик дает ошибку. Это уже не АВР, это просто Линух и VSCode с GCC.
3. Все еще надеюсь на то, что Женя знает о стандарте больше меня, а так оно и есть, и найдет способ инициализации не интегральных статиков.
==================
У меня пока только такой вариант, может он тебя устроит. Под реалии Ардуины сам переделаешь, ежели чо.
причем в dadaLen нужно писать именно имя _someData - внешнего массива, а не someData. Иначе констэкпр считает неправильно.
Этот пример на принт из стр19. А самое загадочное - принт стр17.
Этот пример на принт из стр19. А самое загадочное - принт стр17.
без этой строки компилятор создает код иначе. Пользуется данными этапа компиляции, в котором он нормально обработал все выражения и статики Дедова класса. А с ней - уже передает линковщику ссылки... которых в реале нет ;))))
---------
И да - это конечно глюк. Вот прям маслице для любителей поругать компилятор! ;))) Логик может плясать. У кого-то есть компилятор лучше?
Я уже вызвал циган с медведями на балалайках!
Дело не в том есть ли лучше. Просто приятно когда чванливый "дартаньян среди пидерастов" на поверку оказывается сам гейфрендли.
Тезис что софта без глюков не бывает теперь можно считать истинным?
вот самый короткий пример:
Да, пример, то у меня короче есть
Результат: в ардуине и в AVR-студии одинаковая ошибка, а в мелкомягком компиляторе и в билдере - всё компилируется на ура.
Вопрос-то всё равно остаётся - что провоцирует такое поведение? Я в этом пытаюсь разобраться. Понятно же, что деду не нужен совет "как сделать, чтобы работало" - это он и без нас отлично сделает. Ему любопытно "чё за хрень". Мне тоже.
То, что программист тут "выпендрился" в общем-то понятно, но компилятор должен был разобраться и либо оставить массив в памяти (наплевав на constexpr), либо развернуть цикл и уйти от переменной в индексе. Но он, похоже, черезчур увлёкся оптимизацией. Ладно, следствие продолжается.
так, посоветуйте теперь дизассемблер, посмотреть, что там накомпилировалось
а шож им дизасемблить если ниче не собралось. Почти уверен что мелкомягкий компилятор просто забил на оптимизацию, вот оно и прошло :) Иногда лучший подход к проблеме - забить хер. В данном случае забили оптимизировать.
Да, пример, то у меня короче есть
Результат: в ардуине и в AVR-студии одинаковая ошибка, а в мелкомягком компиляторе и в билдере - всё компилируется на ура.
Женя! Это глюк GCC, свой пример я компилировал просто на компе. Линух Минт 64 бита.
ну да. Вот пример Жени на GCC 5.4.0.
Опять ошибка от линковщика.
вот обход. Мне всегда только это интересно. Ошибки в софте, даже таком проверенном миллионами, как GCC - нормально.
===============
Я не нашел, где бы в стандарте было РАЗРЕШЕНО инициализировать статик элементы неинтегрального (хотя по русски надо говорить "несчетного") типа. Если некоторые компиляторы это пропускают - здорово.
Плохо, что GCC на этапе компиляции не ругается, но и не создает массив в памяти. Это глюк. Надо о нём знать.
вот обход. Мне всегда только это интересно. Ошибки в софте, даже таком проверенном миллионами, как GCC - нормально.
Золотые слова! С этим фактом надо жить. И писать в обход глюков. И писать проще, оно так всем приятней, и компилятору и читателям. И не спешить лезть в С++17 и прочие тяжкие.
Вопрос-то всё равно остаётся - что провоцирует такое поведение? Я в этом пытаюсь разобраться. Понятно же, что деду не нужен совет "как сделать, чтобы работало" - это он и без нас отлично сделает. Ему любопытно "чё за хрень". Мне тоже.
Да. Я понять хочу, с тем ли канпилятором я связался. :-) итииемать.
Пошто я в Дельфи могу инкапсулировать в класс все, что угодно, а в этомязыке могу, канеш, тока как то черезжопу и не всегда. :-)
Вопщем, нада, хлебнув кваску, писать свой канпилятор, с преферансом и библиотекаршами.
И этта. До понедельника мы с котом - ватключке. :-)
Да. Я понять хочу, с тем ли канпилятором я связался. :-) итииемать.
Не, ну, ты сам то пиши правильно! Твой вопрос же не о прямой ошибке компилятора, а о неправильной реакции на ошибку программиста, разве не так? Если бы ты написал правильно, то и проблем бы не было. А так, ты, конечно прав, он должен был либо ругнуться, либо послать твой constexpr и разместить массив в памяти (может ещё предупреждение выдать). А он, сволочь, пропустил молча и подсунул свинью линкеру.
В стандарте прямо сказано (разд 12.2.3.2(3) на стр. 249): "If a non-volatile non-inline const static data member is of integral or enumeration type, its declaration in the class definition can specify a brace-or-equal-initializer in which every initializer-clause that is an assignment-expression is a constant expression. The member shall still be defined in a namespace scope if it is odr-used in the program and the namespace scope definition shall not contain an initializer".
Большинство компиляторов позволяют этого не делать (не размещать определение), GCC тоже позволяет, но, как показала практика, не всегда корректно.
Т.е. если мы напишем точно по стандарту (твой .h файл)
то GCC глючить не будет - я запускал со всеми раскомментированными строками - всё нормально пашет. А вот его реакция на нашу ошибку глюкавая.
Важное замечание: разумеется добавленное мною определение нужно не в .h файле размещать, а то плодиться начнёт.
Блин, целый день траха чтобы понять, что GCC, видя constexpr изо всех сил пытается не размещать его в памяти, а когда не получается, (А) не проверяет есть ли уже размещение и (Б) не размещает сам.
Спасибо ЕвгенийП за подробное объяснение, свою ошибку я понял. С++ дает инициализировать в описании только простенькие, "импотентские" типы. Другие инициализаторы надо пхать в cpp файл. Акей.
Стандарты не читал, но осуждаю, как Пастернака. :)
Опщем, можно тему удалять. :-)
Опщем, можно тему удалять. :-)
пока я не въеду о чём вы тут наговорили на 75 постов низзя