Articles of language lawyer

Почему основные компиляторы используют typedef для stdint.h, но используют #define для stdbool.h?

Я только заметил, что gcc и clang оба, похоже, используют typedefs для stdint.h, но #define для stdbool.h. Например: clang’s stdint.h #ifdef __INT8_TYPE__ #ifndef __int8_t_defined /* glibc sys/types.h also defines int8_t*/ typedef __INT8_TYPE__ int8_t; #endif /* __int8_t_defined */ typedef __UINT8_TYPE__ uint8_t; # define __int_least8_t int8_t # define __uint_least8_t uint8_t #endif /* __INT8_TYPE__ */ clang’s stdbool.h #ifndef […]

смешанный знак целочисленной математики зависит от переменной размерности

Функции g1() и g2() имеют идентичную логику, но типы ввода имеют разные размеры. Почему они возвращают разные результаты для отрицательных сумм? /*BINFMTCXX: -Wall -Werror -Wextra -std=c++11 */ #include #include char g1( int32_t a, uint32_t b ) { return a+b<9; } // fails when a+b is negative char g2( int16_t a, uint16_t b ) { return […]

Неполный тип массива?

Когда я скомпилировал следующий код с gcc -Wall -pedantic -ansi -std=c89 , он скомпилировался успешно, не давая ошибки при назначении указателя. Обратите внимание, что я конвертирую из int (*)[4] в int (*)[] . int arr[4]; int (*p_arr)[] = &arr; Предполагая, что есть какая-то причина для разрешения этого (несовместимого?) Присваивания, когда я пытаюсь его использовать, компилятор […]

Макрос __is_constexpr для Linux Kernel

Как работает __is_constexpr(x) ядра Linux? В чем его цель? Когда это было введено? Почему это было введено? /* * This returns a constant expression while determining if an argument is * a constant expression, most importantly without evaluating the argument. * Glory to Martin Uecker */ #define __is_constexpr(x) \ (sizeof(int) == sizeof(*(8 ? ((void *)((long)(x) […]

Обнаружение целых выражений целых чисел в макросах

В списке рассылки ядра Linux была обсуждена макрос, который проверяет, является ли его аргумент целочисленным константным выражением и является самим выражением целочисленного константы. Один особенно умный подход, который не использует встроенные функции, предложенные Мартином Уэккером (берущий вдохновение от tgmath.h glibc), таков : #define ICE_P(x) (sizeof(int) == sizeof(*(1 ? ((void*)((x) * 0l)) : (int*)1))) Этот макрос […]

Строгое наложение и наложение наложения

Рассмотрим этот пример кода: #include typedef struct AA; struct A { int x; int y; }; typedef struct BB; struct B { int x; int y; int z; }; int main() { B b = {1,2,3}; A *ap = (A*)&b; *ap = (A){100,200}; //a clear http://port70.net/~nsz/c/c11/n1570.html#6.5p7 violation ap->x = 10; ap->y = 20; //lvalues of […]

Смежные символы и строковые литералы

Это знакомый факт, что в C вы можете написать “a” “b” и получить “ab” . Это обсуждается в стандарте C11 : В фазе 6 трансляции многобайтовые последовательности символов, заданные любой последовательностью соседних символов и тождественно-префиксов строковых литералов, объединены в одну многобайтовую последовательность символов. Фраза «character and …» показала бы, что вы можете получить те же […]

Совместимые типы и игнорирование квалификаторов верхнего уровня в системе типа C

Это многочастный вопрос. Я пытался понять систему типа C. Сначала в стандарте C много упоминается термин «совместимый тип», поэтому я попытался это понять. Определение, похоже, довольно распространено, но из того, что я нашел: 6.2.7 Совместимый тип и составной тип 1 Два типа имеют совместимый тип, если их типы одинаковы. Дополнительные правила для определения совместимости двух […]

Порядок разрешения операндов C и C ++

Много раз я вижу (и иногда пишу) код, похожий на этот пример: int a=0, b=2; if( a && (b=func())!=0 ) { //… Вопрос в том, подтверждает ли стандарт эти утверждения? b не будет касаться (и останется значением 2 ) func() не будет вызвана И наоборот, если мы напишем if( func()!=0 && a ) – будет […]

Можем ли мы повторно использовать выделенную память

Это является продолжением этого вопроса . Объясняя мою проблему, я объявил, что выделенная память может быть повторно использована, потому что у нее нет объявленного типа, и мне сказали, что это неверно C. Вот пример кода, иллюстрирующий вопрос: #include #include #include #include struct Elt { int id; char name[32]; }; struct Elt2 { double val; char […]