J'ai un *.cpp
fichier que je compile avec C ++ (pas un compilateur C). La fonction contenant repose sur un cast (voir dernière ligne) qui semble être défini en C (veuillez corriger si je me trompe!), Mais pas en C ++ pour ce type spécial.
[...] C++ code [...]
struct sockaddr_in sa = {0};
int sockfd = ...;
sa.sin_family = AF_INET;
sa.sin_port = htons(port);
bind(sockfd, (struct sockaddr *)&sa, sizeof sa);
[...] C++ code [...]
Puisque je compile ceci dans un fichier C ++, est-ce que ce comportement est maintenant défini ou non défini? Ou aurais-je besoin de déplacer cela dans un *.c
fichier, pour en faire un comportement défini?
c++
c
undefined-behavior
Daniel Stephens
la source
la source
.c
extension, le compilateur C est appelé automatiquement.Réponses:
Ceci est défini à la fois en C ++ et en C. Il ne viole pas les règles strictes d'alias car il ne déréférence pas le pointeur résultant.
Voici la citation de C ++ (grâce à @interjay et @VTT) qui permet cela:
Voici la citation de C (merci @StoryTeller) qui permet cela:
Ceux-ci spécifient qu'un type de pointeur peut être converti en un autre type de pointeur (puis éventuellement reconverti) sans conséquence.
Et voici la citation de POSIX qui permet ce cas spécifique:
Comme cette fonction (
bind
) fait partie de la bibliothèque standard C, tout ce qui se passe à l'intérieur (en particulier, déréférencer le pointeur transtypé) n'a pas de comportement non défini.Pour répondre à la question plus générale:
C et C ++ sont deux langages différents. Si quelque chose est défini en C mais pas en C ++, il est défini en C mais pas en C ++. Aucune compatibilité implicite entre les deux langues ne changera cela. Si vous souhaitez utiliser du code bien défini en C mais non défini en C ++, vous devrez utiliser un compilateur C pour compiler ce code.
la source
bind
devrait être unconst void *
, maisbind
est antérieur à l'existence devoid
dans le langage C (et à l'existence de C ++ du tout). Ils l'ont mis à jour à un moment donné pour ajouter leconst
, mais n'ont jamais fixé le type de base.Les appels entre le code C et C ++ invoquent tous un comportement indéfini, du point de vue des normes respectives, mais la plupart des plateformes spécifient de telles choses.
Dans les situations où des parties de la norme C ou C ++ et la documentation d'une implémentation définissent ou décrivent ensemble une action, mais que d'autres parties la caractérisent comme non définie, les implémentations sont autorisées à traiter le code de la manière qui répondrait le mieux aux besoins de leurs clients ou - si elles sont indifférents aux besoins des clients - quelle que soit la mode qu'ils jugent appropriée. Le fait que la Norme considère ces questions comme ne relevant pas de leur juridiction n'implique aucun jugement quant au moment et / ou à la manière dont les implémentations revendiquant l'adéquation à diverses fins devraient être censées les traiter de manière significative, mais certains responsables du compilateur souscrivent à un mythe selon lequel il le fait.
la source