Давайте посмотрим на следующий код, который я для примера выдрал из ядра linux:
if (!strncmp(name, p, k) && p[k] == '=') {
p += k + 1;
...
Много загадочного и непонятного скрывает в себе мир вообще и мир программирования в частности.
Не запутаться бы.
if (!strncmp(name, p, k) && p[k] == '=') {
p += k + 1;
...
-Weffc++, -Woverloaded-virtual, -Wold-style-cast). Я не пробовал включать их для си, могу предположить, что последует ругань и правильно. А поскольку для C они не имеют смысла - в данном контексте они не интересны.-Wsign-conversion -Wconversion -pedantic. Остановимся на них поподробнее.enum {
TEST1 = 0x100000000ULL,
TEST2 = 0xffffffffU,
TEST3 = 0x7fffffff
};
$ gcc -c -std=c99 -pedantic test.c
test.c:2: предупреждение: в ISO C значения перечислимого типа ограничены диапазоном типа ‘int’
test.c:3: предупреждение: в ISO C значения перечислимого типа ограничены диапазоном типа ‘int’Причем это справедливо и для amd64, в этом легко убедиться например так:BOOST_STATIC_ASSERT(sizeof(int) == 4);В то же время в C++ с enum не возникает никаких проблем. В C++ тип enum есть собственно enum, даже знаковость которого определяется позже. Единственный возникающий в данной ситуации момент - стандарт C++ 99 года не любит определений ULL, считая их C99 long long integer constant, Для C++ даже U писать не обязательно, главное, чтобы значение могло уместиться в long, то есть быть не больше 32-64 бит в зависимости от типа платформы.
sizeof(TEST1) в С++ варьируется в зависимости от наполнения enum от 4 до 8.const unsigned int t1 = TEST1; const unsigned int t2 = 0; const unsigned int t3 = argc > 1 ? TEST1 : 0; $ gcc -m64 -o test -std=c99 -Wsign-conversion test.c test.c:3: предупреждение: conversion to ‘unsigned int’ from ‘int’ may change the sign of the resultОшибка возникает в третьей строке фрагмента, и лечится заменой 0, на 0U... Хотя тот же 0 во второй строке не вызывает проблем.
unsigned int x = 0x7f;
struct {
unsigned int a:7;
} t = { .a = x };
$ gcc -std=c99 -Wconversion test.c
test.c:4: предупреждение: conversion to ‘unsigned char:7’ from ‘unsigned int’ may alter its valueНе существует способа привести переменную к битовому полю.Что касается женщин, то это чувство сугубо интимное...
if (MIN_ELEMENTS == i) ...Я долго не мог понять почему мне это так не нравится, и наконец сформулировал для себя ответ на этот вопрос.
if (MIN_ELEMENTS <= i && i <= MAX_ELEMENTS) ...Очень похожая ситуация, хотя меня она коробит меньше.
Если MIN_ELENEMTS равен...Стоп, как может быть константное значение сегодня равно, а завтра не равно? В этом выражении как будто содержится предположение, что MIN_ELEMENTS может измениться.
i равно чему-то; если i равно MAX_ELEMENTS...Все последовательно и логично. Но это если код читать... Если воспринимать код целостно, то, возможно, все воспринимается несколько иначе.
KernelWait:
pushfl
pushl %ebx
pushl %ecx
pushl %edx
pushl %esi
pushl %edi
pushl %ebp
pushl %ds
pushl %es
movl $KERNEL_DATA_SELECTOR, %ebx
movw %bx, %ds
movw %bx, %es
pushl %edx
pushl %ecx
pushl %ebx
pushl %eax
call StubWait
add $16, %esp
popl %ds
popl %es
popl %ebp
popl %edi
popl %esi
popl %edx
popl %ecx
popl %ebx
popfl
iret
KernelWait:
...
pushl %edx
pushl %ecx
pushl %ebx
pushl %eax
call StubWait
add $4, %esp
popl %edx
popl %ecx
popl %ebx
...
iret
int StubWait (int a, int b, int c, int d)
{
d += 10;
int StubWait (const int a, const int b, const int c, const int d)
{
int dnew = d + 10;
static const
struct console StubXGAConsole = {
.putc = StubXGAPutC,
.getc = StubXGAGetC,
};
static const
struct console *sConsole = &StubXGAConsole;