Ce n'est pas un Comportement Indéfini, c'est juste une modification de rupture dans la norme du langage C entre C89 et C99.
En C89, les constantes entières comme 4008636143 qui ne rentrent pas dans un int
ou long int
mais ne fit en unsigned int
ne sont pas signés, mais en C99, ils sont soit long int
ou long long int
(selon celle qui est la plus petite qui peut contenir la valeur). En conséquence, les expressions sont évaluées à l'aide de 64 bits, ce qui entraîne une mauvaise réponse.
Visual Studio est un C89 compilateur et donc les résultats dans le C89 comportement, mais que Ideone lien est en train de compiler en C99 mode.
Cela devient encore plus évident si l'on compile avec GCC en utilisant -Wall
:
test.c: In function ‘divisible15':
test.c:8:3: warning: this decimal constant is unsigned only in ISO C90
De C89 §3.1.3.2:
Le type d'une constante entière est la première de l'correspondant
liste dans laquelle sa valeur peut être représentée. Unsuffixed décimal: int,
long int, unsigned long int; unsuffixed octal ou hexadécimal: int,
unsigned int, long int, unsigned long int; [...]
C99 §6.4.4.1/5-6:
5) Le type d'une constante entière est le premier de la liste correspondante dans lequel sa valeur peut
être représentée.
Suffix | Decimal Constant | Octal or Hexadecimal Constant
-------+------------------+------------------------------
none | int | int
| long int | unsigned int
| long long int | long int
| | unsigned long int
| | long long int
| | unsigned long long int
-------+------------------+------------------------------
[...]
6) Si une constante entière ne peut pas être représenté par n'importe quel type dans sa liste, il peut avoir une
étendue de type entier, si l'étendue de type entier peut représenter sa valeur. Si toutes les
types dans la liste de la constante sont signés, l'étendue de type entier doit être signé. [...]
Pour être complet, C++03 réellement n'avez pas défini de Comportement pour quand la constante entière est trop gros pour rentrer dans un long int
. À Partir De C++03 §2.13.1/2:
Le type d'un littéral entier dépend de sa forme, de la valeur, et le suffixe. Si c'est décimal et n'a pas de suffixe, il a
le premier de ces types dans lequel sa valeur peut être représentée: int
, long int
; si la valeur ne peut pas être représenté
en tant que long int
, le comportement est indéfini. Si c'est octal ou hexadécimal et n'a pas de suffixe, il a l'
la première de ces types dans lequel sa valeur peut être représentée: int
, unsigned int
, long int
, unsigned
long int
. [...]
Le C++11 comportement est identique à C99, voir C++11 §2.14.2/3.
Pour s'assurer que le code se comporte de manière uniforme lors de la compilation comme C89, C99, C++03, et de C++11, la seule solution est de faire de la constante 4008636143 non signé en suffixant il avec u
comme 4008636143u
.