jcxz 242 15 октября, 2023 Опубликовано 15 октября, 2023 · Жалоба 14 минут назад, repstosw сказал: Тоесть, вердикт: GCC - крут, а IAR- нет! В чём крут? В том, что пропустил баг ваших исходников? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 15 октября, 2023 Опубликовано 15 октября, 2023 (изменено) · Жалоба 10 minutes ago, jcxz said: В чём крут? В том, что пропустил баг ваших исходников? Более лоялен к синтаксису. И поддерживает больше интересностей, наподобие: typeof, локальные метки. И кстати, арифметику с указателем void ИАР запрещает. Что-то вроде: void *p; p+=7; выдаст ошибку. А GCC правильно полагает, что дефолтная размерность указателя - 1 байт. IAR требует char*. А C++ туповат, потому что не позволяет malloc стипкастить на не-void указатель. В обычном Си это прокатывет. char *p=malloc(7); Изменено 15 октября, 2023 пользователем repstosw Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 187 15 октября, 2023 Опубликовано 15 октября, 2023 · Жалоба 16 минут назад, repstosw сказал: Ещё IAR не может в локальные метки. Что-то наподобие: #define TTT(x) \ { \ int y; \ local m1: \ y=test(x); \ if(y)goto m1; \ printf("%d\n",y); \ } \ void main(void) { TTT(2); TTT(23); TTT(234); } Вариант сделать TTT - функцией - не засчитываетя 🙂 А такой? #define TTT(x) \ { \ int y; \ concat2(__m, __LINE__): \ y=test(x); \ if(y) goto concat2(__m, __LINE__); \ printf("%d\n",y); \ } 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 15 октября, 2023 Опубликовано 15 октября, 2023 · Жалоба 1 minute ago, Arlleex said: А такой? #define TTT(x) \ { \ int y; \ concat2(__m, __LINE__): \ y=test(x); \ if(y) goto concat2(__m, __LINE__); \ printf("%d\n",y); \ } Засчитан. Конструктор имён меток. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 187 15 октября, 2023 Опубликовано 15 октября, 2023 · Жалоба 10 минут назад, repstosw сказал: void *p; p+=7; выдаст ошибку. И правильно сделает. Ибо арифметика с void-указателями - расширение GNU. 12 минут назад, repstosw сказал: А C++ туповат, потому что не позволяет malloc стипкастить на не-void указатель. В обычном Си это прокатывет. char *p=malloc(7); Ну, вообще говоря, C++ был так спроектирован, и очень хорошо, что не позволяет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 15 октября, 2023 Опубликовано 15 октября, 2023 (изменено) · Жалоба 4 minutes ago, Arlleex said: И правильно сделает. Ибо арифметика с void-указателями - расширение GNU. 4 minutes ago, Arlleex said: Ну, вообще говоря, C++ был так спроектирован, и очень хорошо, что не позволяет. Вы это линухоедам расскажите У них в исходниках можно найти много чего интересного. P.S. Торвальдс против С++ для ядра Линукс... Изменено 15 октября, 2023 пользователем repstosw Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 187 15 октября, 2023 Опубликовано 15 октября, 2023 · Жалоба Линухоеды пишут только на GCC, поэтому им позволительно. Но не позволительно тем, кто пишет мало мальски переносимое ПО. Более того: программистов миллионы, "программистов" - еще больше, поэтому выделять некую условную группу в разряд авторитетов - не моя тема🙂 3 минуты назад, repstosw сказал: P.S. Торвальдс против С++ для ядра Линукс... Переписать миллионы строк кода лишь для того, что плюсы - другой язык программирования - я бы тоже не стал. Это первоочередная причина... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 15 октября, 2023 Опубликовано 15 октября, 2023 · Жалоба 4 minutes ago, Arlleex said: Переписать миллионы строк кода лишь для того, что плюсы - другой язык программирования - я бы тоже не стал. Это первоочередная причина... Речь не о переделывании готового. А о добавлении нового, которое разрешается писать только на Си. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 242 15 октября, 2023 Опубликовано 15 октября, 2023 · Жалоба 27 минут назад, repstosw сказал: И поддерживает больше интересностей, наподобие: typeof, локальные метки. Наличие поддержки одного только префикса __packed у IAR перекрывает с лихвой все те ненужные "интересности". Есть у GCC аналог __packed? 27 минут назад, repstosw сказал: И кстати, арифметику с указателем void ИАР запрещает. А GCC правильно полагает, что дефолтная размерность указателя - 1 байт. IAR требует char*. Имхо - и правильно делает. А GCC неправ. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 187 15 октября, 2023 Опубликовано 15 октября, 2023 · Жалоба Насколько мне известно, требование писать на Си не выше определенного уровня оптимизации (по-моему, -O2) относится только к ядру линукса. Понятно, что притащив туда C++ нужно будет многое изменять в abi, системе исключений и сопряжении со стандартными библиотеками C++. Это весьма большой объем работы, причем - на ровном месте. Плюсы такого консерватизма - плюс-минус стабильное ядро в перерасчете на его сложность и затраченные человеко-часы. К тому же - на Си в лоб сложнее написать трудночитаемый кусок, в отличие от плюсов, где каждый программист блещет скиллом как захочет. 2 минуты назад, jcxz сказал: Есть у GCC аналог __packed? Есть. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 15 октября, 2023 Опубликовано 15 октября, 2023 · Жалоба 11 minutes ago, jcxz said: Наличие поддержки одного только префикса __packed у IAR перекрывает с лихвой все те ненужные "интересности". Есть у GCC аналог __packed? Это который разрешает невыровненный доступ к данным? Испольую такое: #define __PACKED_STRUCT struct __attribute__((packed,aligned(1))) #define __UNALIGNED_U32_READ(addr) (((const struct T_U32_READ*)(const void*)(addr))->v) #define __UNALIGNED_U32_WRITE(addr,val) (void)((((struct T_U32_WRITE*)(void*)(addr))->v)=(val)) __PACKED_STRUCT T_U32_READ{u32 v;}; __PACKED_STRUCT T_U32_WRITE{u32 v;}; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 242 15 октября, 2023 Опубликовано 15 октября, 2023 · Жалоба 13 минут назад, repstosw сказал: Это который разрешает невыровненный доступ к данным? Нет. Это который отключает выравнивание для переменной или структуры. __packed uint x1; __packed struct T1 { char y1; uint y2; char y3; }; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
repstosw 18 15 октября, 2023 Опубликовано 15 октября, 2023 · Жалоба 1 minute ago, jcxz said: Нет. Это который отключает выравнивание для переменной или структуры. Только для структуры Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 187 15 октября, 2023 Опубликовано 15 октября, 2023 · Жалоба 10 минут назад, repstosw сказал: Это который разрешает невыровненный доступ к данным? Испольую такое: #define __PACKED_STRUCT struct __attribute__((packed,aligned(1))) #define __UNALIGNED_U32_READ(addr) (((const struct T_U32_READ*)(const void*)(addr))->v) #define __UNALIGNED_U32_WRITE(addr,val) (void)((((struct T_U32_WRITE*)(void*)(addr))->v)=(val)) __PACKED_STRUCT T_U32_READ{u32 v;}; __PACKED_STRUCT T_U32_WRITE{u32 v;}; Бррр... typedef struct __attribute__((packed)) { char c; int i; }PackedStr; void func(void) { __unaligned int *p = &PackedStr.i; ... *p; // ok, access is unaligned } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 242 15 октября, 2023 Опубликовано 15 октября, 2023 · Жалоба Только что, repstosw сказал: Только для структуры Не только. См. мой пример. 1 минуту назад, Arlleex сказал: Бррр... typedef struct __attribute__((packed)) { char c; int i; }PackedStr; void func(void) { __unaligned int *p = &PackedStr.i; ... *p; // ok, access is unaligned } А такое: typedef __packed u16 u16p8; typedef __packed s16 s16p8; typedef __packed u32 u32p8; typedef __packed s32 s32p8; typedef __packed u64 u64p8; typedef __packed s64 s64p8; typedef __packed u32 u32p16; typedef __packed s32 s32p16; typedef __packed u64 u64p16; typedef __packed s64 s64p16; typedef __packed u64 u64p32; typedef __packed s64 s64p32; typedef __packed float floatP8; typedef __packed float floatP16; typedef __packed double doubleP8; typedef __packed double doubleP16; typedef __packed double doubleP32; Возможно? И чтобы потом, работа с переменными, объявленными с таким типом, шла нормально на всех CPU - как с аппаратным выравниванием (Cortex-M) так и без оного (классические ARM7/9)? u32p8 x; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться