В следния код аз memset()
stdbool.h
bool
променлива до стойност 123
. (Може би това е недефинирано поведение?) След това предавам указател към тази променлива към функция жертва, която се опитва да защити срещу неочаквани стойности с помощта на условна операция. Въпреки това GCC по някаква причина изглежда премахва напълно условната операция.
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
void victim(bool* foo)
{
int bar = *foo ? 1 : 0;
printf("%d\n", bar);
}
int main()
{
bool x;
bool *foo = &x;
memset(foo, 123, sizeof(bool));
victim(foo);
return 0;
}
user@host:~$ gcc -Wall -O0 test.c user@host:~$ ./a.out 123
Това, което прави това особено досадно, е, че функцията victim()
всъщност е в библиотека и ще се срине, ако стойността е по-голяма от 1.
Възпроизведено на GCC версии 4.8.2-19ubuntu1 и 4.7.2-5. Не се възпроизвежда на clang.
x
катоbool
, вие сте обещали на компилатора, че ще съхранявате само0
или1
в него. Съхранявайки123
вx
1, вие сте излъгали компилатора. Ако излъжете компилатора, той ще си отмъсти. -- Хенри Спенсър - person Keith Thompson   schedule 26.12.2014CHAR_BIT
бита (иCHAR_BIT >= 8
), той също е достатъчно голям, за да побере стойността123
. Не сте възпрепятствани да съхранявате123
вbool
обект поради неговия размер, но това е недефинирано поведение. - person Keith Thompson   schedule 26.12.2014<stdbool.h>
заглавие, можете да обмислите използването само наtrue
иfalse
стойност (точно както в Pascal с типBoolean
). Това ще направи кода ви малко по-четлив и ще ви държи далеч от други стойности. - person Grzegorz Szpetkowski   schedule 27.12.2014true
като битов модел01111011
. По-важното е, че може да избере11111111
като модел на битове заtrue
. Преобразуването наtrue
вint
трябва да даде 1, но това не ограничава битовия модел наtrue
. (Сравнете:1.0f
сint
.) - person MSalters   schedule 27.12.2014bool
е целочислен тип и трябва да следва същите правила като другите цели числа.true
е макрос, дефиниран в<stdbool.h>
, който се разширява до1
. Ако присвояването на стойност1
наbool
обект задава неговия модел на битове на11111111
, тогава 7-те бита от висок ред трябва да бъдат битове за допълване. (И всичко-битове-нула трябва да бъде представяне за0
, макар и не непременно единственото представяне.) - person Keith Thompson   schedule 27.12.20140111101
преди бита за стойност1
? И по същество коментарът, на който отговорих, приема, че тези битове задължително трябва да са нула, което според мен е особено невярно. - person MSalters   schedule 27.12.2014_Bool
заговорничат да направят нещата объркващи по начини, които ме мързи да изследвам в момента. Най-долу: Съхраняването на стойности, различни от0
и1
в_Bool
обект, е нещо, което трябва да се избягва. - person Keith Thompson   schedule 27.12.2014