Перейти к содержанию
    

Указатель на невыровненную память

#pragma pack(push, 1)                                                                   
struct PackStr {                                                                        
  u64 d64;                                                                              
};                                                                                      
#pragma pack(pop)                                                                       
                                                                                        
volatile struct {                                                                       
  u8      d8;                                                                           
  PackStr p64;                                                                          
                                                                                        
                    In section .bss, align 4                                            
} UnalignStr;                                                                           
        UnalignStr:                                                                     
                    DS8 12                                                              
                                                                                        
                                                                                        
                    In section .text, align 2, keep-with-next                           
int main1() {                                                                           
  UnalignStr.p64.d64; // <- какая инструкция CPU для Cortex-M4 будет применена?         
  return 1;                                                                             
        _Z5main1v: (+1)                                                                 
 0x2001             MOVS     R0,#+1                                                     
 0x4770             BX       LR               ;; return                                 
}                                                                                       

IAR v7.80.4

Плюс:

Цитата

Warning[Pe174]: expression has no effect D:\...xxx.cpp

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Только что, jcxz сказал:
#pragma pack(push, 1)                                                                   
struct PackStr {                                                                        
  u64 d64;                                                                              
};                                                                                      
#pragma pack(pop)                                                                       
                                                                                        
volatile struct {                                                                       
  u8      d8;                                                                           
  PackStr p64;                                                                          
                                                                                        
                    In section .bss, align 4                                            
} UnalignStr;                                                                           
        UnalignStr:                                                                     
                    DS8 12                                                              
                                                                                        
                                                                                        
                    In section .text, align 2, keep-with-next                           
int main1() {                                                                           
  UnalignStr.p64.d64; // <- какая инструкция CPU для Cortex-M4 будет применена?         
  return 1;                                                                             
        _Z5main1v: (+1)                                                                 
 0x2001             MOVS     R0,#+1                                                     
 0x4770             BX       LR               ;; return                                 
}                                                                                       

IAR v7.80.4

Плюс:

Ну, не знаю, что тут можно сказать. Баг это IAR или нет - не берусь утверждать. Но вообще говоря, очень широкораспространенная практика фиктивного чтения volatile-ов (лишь для самого факта чтения, без использования значения далее) - это либо как я написал, либо с припиской (void).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

45 минут назад, Arlleex сказал:

Ради интереса, даже GCC.

Просто чудный компилятор - даже на отсутствие return в int main() не обратил внимания.  :shok:

Может у вас там вообще все варнинги подавлены?  :wink:

Я пожалуй поостерегусь таким впредь компилировать.  :wink:

6 минут назад, Arlleex сказал:

Но вообще говоря, очень широкораспространенная практика фиктивного чтения volatile-ов (лишь для самого факта чтения, без использования значения далее) - это либо как я написал, либо с припиской (void).

Лучше написать как я написал: u64 q = UnalignStr.p64.d64;

Или даже: { u64 q = UnalignStr.p64.d64; }

и не создавать проблем.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

10 минут назад, jcxz сказал:

Просто чудный компилятор - даже на отсутствие return в int main() не обратил внимания.  :shok:

Может у вас там вообще все варнинги подавлены?  :wink:

Нет, не подавлены. Есть варнинг - но весьма незначительный и совершенно в другом месте.

Насчет return: (я уже всех достаточно задолбал со стандартами? или пока нет:biggrin:) main - это особый случай, и можно не писать в его конце return N.

По умоланию, если return N отсутствует, то компилятор считает, что там return 0. Поэтому да, компилятор - топ, все по делу и правильно сделал))

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

10 минут назад, Arlleex сказал:

Насчет return: (я уже всех достаточно задолбал со стандартами?:biggrin:😞 main - это особый случай, и можно не писать в его конце return N.

По умоланию, если return N отсутствует компилятор считает, что там return 0. Поэтому да, компилятор - топ, все по делу и правильно сделал))

Печально это. Так же как и молчаливое пропускание передачи char const * в аргументы функций, принимающих char *.  :sad:

Не хочешь ничего возвращать? Пиши void main(). какие проблемы?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, jcxz сказал:

Не хочешь ничего возвращать? Пиши void main(). какие проблемы?

Насколько я понял, main() не может ничего не возвращать, т.к. ее (в общем случае) вызывает какая-то сущность, чаще всего - операционная система.

Поэтому, видимо, исторически везде так и осталось - int main().

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 часа назад, jcxz сказал:

Печально это. Так же как и молчаливое пропускание передачи char const * в аргументы функций, принимающих char *.  :sad:

Тоже объяснимо, но в нынешних реалиях мало соотносится с логикой.

Я полагаю, Вы имели в виду вызов func("string"), где void func(char *str). Проблема в том, что в Си строка (строковый литерал) имеет тип char [] (не char * и не const char *). Поэтому компиляция "перлов" в виде func("string") происходит молча. Ну хоть в C++ это уже не пройдет - там символьная строка имеет тип char const [].

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 10/22/2023 at 9:27 PM, Arlleex said:

Ну хоть в C++ это уже не пройдет - там символьная строка имеет тип char const [].

в Rust все переменные и ссылки на них по умолчнию неизменяемые и там можно спокойно написать a = b потому вывод типов автоматический а код просто не скомпилируется при любой неопределённости, закапывайте свой С++.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

14 часов назад, Arlleex сказал:

Насколько я понял, main() не может ничего не возвращать, т.к. ее (в общем случае) вызывает какая-то сущность, чаще всего - операционная система.

Может. По крайней мере у IAR:

                    In section .text, align 4, keep-with-next             
__noreturn __task void main()                                             
{                                                                         
        main: (+1)                                                        
 0xB082             SUB      SP,SP,#+8                                    
  #pragma section = ".intvec"                                             
  #pragma section = ".codetail"                                           
  #pragma section = ".codeheadExt"                                        
  #pragma section = ".codetailExt"                                        
  FaultCpuDis();                                                          
 0x.... 0x....      BL       FaultCpuDis                                  
  IntCpuDis();                                                            
 0x.... 0x....      BL       IntCpuDis
...

Как видите - прекрасно компилится void main().

Более того - в мануале какого-то компилятора (точно не помню, но вроде CCS от TI) видел явное указание, что "если хотите ничего не возвращать из main(), то, в качестве стартапа, следует подключить другой специальный стартап, вызывающий вариант void main(), вместо int main()".

А у IAR-а видимо стартап написан для двух перегруженных вариантов main(). Автоматом выбирается нужный.

1 час назад, sasamy сказал:

в Rust все переменные и ссылки на них по умолчнию неизменяемые и там можно спокойно написать a = b потому вывод типов автоматический а код просто не скомпилируется при любой неопределённости, закапывайте свой С++.

Не понимаю о чём тут речь? и почему c++ нужно "закапывать"? В си++ тоже "можно спокойно написать a = b" сколь бы ни было это удивительным для вас.  :sarcastic:

ЗЫ: c++ ещё нас с вами переживёт. И тем более - все эти новомодные финтифлюшки: rustы и т.п.  Сколько их уже было всяких за время существования си/си++? кто их сейчас вспомнит?  :unknw:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 hours ago, jcxz said:

Как видите - прекрасно компилится void main().

да,

стартап, если на ассемблере написанный, просто делает call main, и что там за тип у main (в случае с С без возможности перегрузки функций как у С++ и name mangling), и вернёт она обратно что-нибудь стартапу или не вернёт ему вообще без разницы. слинкуется в любом случае, ну а то что main ничего обратно в нужный регистр (ну или куда там надо, в зависимости от соглашении о вызовах) не положил на выходе, и там будет какой-то мусор - ни на что всё равно не повлияет.

а если стартап код на С, то ему при линковке неправильный тип main может и не понравиться

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

19 hours ago, jcxz said:

Просто чудный компилятор - даже на отсутствие return в int main() не обратил внимания.  :shok:

Проверил с -Wall -Wextra -pedantic.  Да, действительно пропускает 🤣

 

17 hours ago, Arlleex said:

Тоже объяснимо, но в нынешних реалиях мало соотносится с логикой.

Я полагаю, Вы имели в виду вызов func("string"), где void func(char *str). Проблема в том, что в Си строка (строковый литерал) имеет тип char [] (не char * и не const char *). Поэтому компиляция "перлов" в виде func("string") происходит молча. Ну хоть в C++ это уже не пройдет - там символьная строка имеет тип char const [].

В защищённых режимах всяких это может вылезти боком. Потому что char const* это Read Only.   А передача char* подразумевает, что в вызываемой функции может производиться запись в память.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, repstosw сказал:

В защищённых режимах всяких это может вылезти боком. Потому что char const* это Read Only.   А передача char* подразумевает, что в вызываемой функции может производиться запись в память.

Это я знаю, но формально стандартом описан тип именно char [] для строковых литералов. К чему это приводит - другой вопрос.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 hours ago, repstosw said:

Проверил с -Wall -Wextra -pedantic.  Да, действительно пропускает 🤣

да вроде имеет право

5.1.2.2.3 Program termination

If the return type of the main function is a type compatible with int, a return from the initial call to the main function is equivalent to calling the exit function with the value returned by the main function as its argument; reaching the } that terminates the main function returns a value of 0. If the return type is not compatible with int, the termination status returned to the host environment is unspecified.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В 22.10.2023 в 18:18, sasamy сказал:

вы уверены что они останутся доступны ?

Уверен!!!
Даже "родные" stm32 вполне покупаются, просто нужно жопу от стула оторвать. А уж китайские клоны так и вовсе в каждом ларьке. Так что без кортексов мы не останемся. А если останемся тогда забота будет достать патроны к АК, керосин, тушенку, спички...

Цитата

Что касается riscv

Еще один камень в могилу риск5. Устроили зоопарк вендор-специфик расширений с несовместимыми компиляторами, разными способами входа в isr, разными стартапами. Тут что-то втирали за "переносимость" встраиваемого ПО между зоопарками ???

Печалит только ESP. 8266 вроде бы не поддерживает а как в esp32 уже не помню. Те которые на xtensa.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

10 hours ago, _pv said:

да вроде имеет право

А меня нервирует, что C++ не любит void main(void). пишет, что main() должен возвращать int. У меня программа постоянно в main() в вечном цикле. Даже освобождение ресурсов не нужно, так как программа работает вечно, пока питание не закончится.

Тут ещё споры разгорелись, по поводу того, если функция не имеет аргументов - надо ли void писать в скобках или нет. Я по всей строгости - пишу void, если нет параметров.  Но коллеги не согласны с моим решением - оставляют пустые скобки.  Это принципиально - для C, а для C++ ?

Изменено пользователем repstosw

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...