2015-10-21 1 views
2

je le code suivant:est d'attribuer un nombre trop grand pour être représenté dans un champ de bits comportement non défini

#include <stdio.h> 
#include <stdint.h> 

enum nums { 
    ONE, 
    TWO, 
    TWENTY = 20 
}; 

struct field { 

    uint32_t something : 4; 
    uint32_t rest : 28; 
}; 

int main(void) { 

    struct field f; 
    f.something = TWENTY; 
    return 0; 
} 

Sur un powerpc 8241 en cours d'exécution RTEMS 4.9.1, compilé avec GCC 3.4.5 MinGW (I connaître son vieux) ce code provoquera un segfault. La raison que j'ai déterminée est que nous mettons un nombre à grand pour être représenté par un champ de bit au champ de bits en question. Puisque nous avons 4 bits, il ne devrait pouvoir représenter que 0 -> 15, et en effet, lorsque nous le configurons avec ces nombres, cela fonctionne très bien. Tout ce qui est au dessus et ça plante. Je suis incapable de reproduire ce comportement here, donc ma question est:

Est-ce un comportement non défini ? Si oui, y a-t-il une référence dans une norme c qui le couvre?

Ou est-ce plus simplement un bogue à cause de notre très ancien compilateur?

+0

Il serait intéressant de compiler avec l'indicateur '-S' pour voir le langage assembleur généré. – lurker

+0

@lurker qui peut probablement être arrangé ... –

+0

Cette question a déjà une réponse ici: http://stackoverflow.com/questions/2151305/gcc-warning-large-integer-implicitly-truncated-to-unsigned-type#2151321 . Si vous ajoutez l'indicateur '-Werror' à GCC, alors la sortie de expectet doit être:' error: grand entier implicitement tronqué au type non signé [-Werror = overflow] f.something = TWENTY; ' – BufferOverflow

Répondre

3

Cela ressemble à un bug, au moins dans ce C99 est de comportement bien défini, du projet C99 section standard 6.2.6 Représentations types:

Values stored in unsigned bit-fields and objects of type unsigned char shall be represented using a pure binary notation.40

et plus tard dans la section 6.2.5 Types:

A computation involving unsigned operands can never overflow, because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting type.