Faut-il suivre la norme, prendre la norme C d'ailleurs?

17

Il y a des gens très expérimentés sur Stack Overflow qui parlent toujours de la norme C. Les gens semblent ne pas aimer les solutions non portables, même si elles fonctionnent pour moi. D'accord, je comprends que la norme doit être respectée, mais ne met-elle pas des entraves à la créativité du programmeur?

Quels sont les avantages concrets qui découlent du respect d'une norme? D'autant plus que les compilateurs peuvent implémenter la norme légèrement différemment.

0 décimal0
la source
7
Pourriez-vous préciser ce que vous entendez par «la norme»? Voulez-vous dire de ne pas réagir à un comportement qui n'est pas défini par la norme? Ou ne pas utiliser d'extensions / fonctionnalités de compilation? Ou des conventions de style?
ikh
1
@ikh He parle des normes ISO C (C90, C99, C11).
Aseem Bansal
9
Cela revient à dire qu'écrire ou parler en anglais, en utilisant la grammaire et le vocabulaire anglais, met à mal votre créativité. Bien sûr, les gens peuvent faire des choses merveilleuses en enfreignant les règles, au détriment de la cohérence, mais vous pouvez écrire des millions de livres créatifs tout en respectant le «standard» de l'anglais.
Avner Shahar-Kashtan
pouvez-vous ajouter un exemple de "Les gens ne semblent pas aimer les solutions non portables, même si elles fonctionnent pour moi"?
BЈовић
1
@PHIfounder Juste pour répondre à ce dernier cas, vous pouvez omettre le retour de main, c'est implicitement retourner 0 :)
Daniel Gratzer

Réponses:

45

Il y a plusieurs raisons pour lesquelles s'en tenir à la norme est une bonne chose.

  1. Être enfermé dans un compilateur, c'est dur. Vous êtes complètement à la merci d'un groupe de développeurs avec leur propre agenda. Ils ne sont évidemment pas là pour vous ou quoi que ce soit, mais si votre compilateur commence à traîner les optimisations, les nouvelles fonctionnalités, les correctifs de sécurité, etc., tant pis; Tu es coincé. Dans des cas extrêmes, certaines entreprises doivent commencer à corriger tout outil dont elles se sont rendues dépendantes. C'est un énorme gaspillage d'argent et de temps lorsqu'il existe d'autres outils de travail.

  2. Être enfermé dans une plate-forme est plus difficile. Si vous utilisez des logiciels sous Linux et que vous souhaitez passer à Windows parce que vous réalisez que votre marché est vraiment là, vous allez avoir du mal à changer chaque hack non portable que vous avez dans votre code pour jouer correctement avec GCC et MSVC. Si vous avez plusieurs éléments de votre conception de base basés sur quelque chose comme ça, bonne chance!

  3. Les changements incompatibles en arrière sont les plus difficiles. La norme ne cassera jamais votre code (Ignorer python). Certains auteurs de compilateurs aléatoires pourraient cependant décider que ce module complémentaire spécifique à l'implémentation ne vaut pas la peine et le laisser tomber. S'il vous arrive de vous y fier, vous êtes bloqué sur la dernière version obsolète dans laquelle il se trouvait.

Donc, le message primordial ici, le respect de la norme vous rend plus flexible . Vous avez une langue plus limitée, mais vous en avez plus

  • Bibliothèques
  • Prise en charge (les gens connaissent la norme, pas tous les hack complexes spécifiques au compilateur)
  • Plateformes disponibles
  • Outils matures
  • Sécurité (résistance future)

C'est un équilibre délicat, mais ignorer complètement la norme est définitivement une erreur. J'ai tendance à organiser mon code C en fonction des abstractions qui pourraient être implémentées de manière non portable, mais que je peux porter de manière transparente sans changer tout ce qui dépend de l'abstraction.

Daniel Gratzer
la source
+1 assez bien :), merci ... J'ai été sérieusement confondu avec la façon dont les compilateurs s'écartaient légèrement des normes et je me suis senti sceptique quant au strict respect, j'avais besoin de connaître les avantages et les inconvénients et vous les avez clairement identifiés.
0 décimal0
6
Un comportement indéfini est également assez nul. Avec c, il est assez facile de s'aventurer dans UB si vous ne suivez pas la norme de près.
CodesInChaos
@CodesInChaos D'accord, un comportement indéfini est excellent d'un côté car il permet des optimisations folles, mais de l'autre le débogage ...
Daniel Gratzer
6

La norme est une sorte de «contrat» entre vous et votre compilateur qui définit la signification de vos programmes. En tant que programmeurs, nous avons souvent un certain modèle mental de fonctionnement du langage, et ce modèle mental est souvent en contradiction avec la norme. (Par exemple, les programmeurs C considèrent souvent un pointeur comme à peu près "un entier qui dénote une adresse mémoire", et supposent donc qu'il est sûr d'effectuer toute arithmétique / conversion / manipulation sur des pointeurs que l'on pourrait effectuer avec un entier qui dénote une mémoire Cette hypothèse n'est pas conforme à la norme; elle impose en fait des restrictions très strictes sur ce que vous pouvez faire avec les pointeurs.)

Alors, quel est l'avantage de suivre la norme, plutôt que votre propre modèle mental?

Autrement dit, c'est que la norme est correcte, et votre propre modèle mental est faux. Votre modèle mental est généralement une vue simplifiée de la façon dont les choses fonctionnent sur votre propre système, dans les cas courants, avec toutes les optimisations du compilateur désactivées; les éditeurs de compilateurs ne font généralement pas d'effort pour s'y conformer, surtout en ce qui concerne les optimisations. (Si vous ne tenez pas votre fin de contrat, vous ne pouvez pas vous attendre à un comportement spécifique de la part du compilateur: garbage in, garbage out.)

Les gens semblent ne pas aimer les solutions non portables, même si elles fonctionnent pour moi.

Il serait peut-être préférable de dire "même s'ils semblent fonctionner pour moi". À moins que votre compilateur ne documente spécifiquement qu'un comportement donné fonctionnera (c'est-à-dire: à moins que vous n'utilisiez une norme enrichie, constituée de la documentation standard appropriée et du compilateur), vous ne savez pas que cela fonctionne vraiment ou qu'il est vraiment fiable. Par exemple, un débordement d'entier signé entraîne généralement un encapsulage sur de nombreux systèmes (ce qui INT_MAX+1est généralement le cas INT_MIN) - sauf que les compilateurs "savent" que l'arithmétique d'entier signé ne déborde jamais dans un programme C (correct) et effectuent souvent des optimisations très surprenantes basées sur ce " connaissance".

ruakh
la source
1
Vous pouvez compiler avec -fwrapv, puis vous utilisez un langage non standard légèrement différent où l'arithmétique d'entier signé est toujours disponible.
user253751
@immibis: Lorsque C89 a été écrit, selon son document de justification, la majorité des compilateurs contemporains ont défini une sémantique de wrapping silencieux pour le débordement d'entier. Dans de nombreux cas, le fait d'avoir certaines sortes de garanties sur ce qui se passe en cas de dépassement d'entier peut permettre au code d'être plus efficace qu'il ne serait possible sans de telles garanties, surtout si les garanties ne vont pas jusqu'à imposer un comportement de wrapping précis [précis le comportement d'habillage peut être émulé en utilisant des mathématiques non signées, mais la sémantique qui est plus lâche mais toujours adéquate pour répondre aux exigences peut permettre un code plus efficace].
supercat
@immibis: Il est dommage que les révisionnistes aient réussi à convaincre les gens que les comportements qui ont été mis en œuvre presque à l'unanimité parmi les compilateurs pour certaines plateformes (ou dans certains cas à 100% à l'unanimité) n'ont jamais été "standard" sur de telles plateformes, car dans de nombreux cas, le la perte d'efficacité résultant de la nécessité d'éviter de tels comportements ne sera pas compensée par les "optimisations" qu'un compilateur a pu réaliser en les révoquant.
supercat
4

Je comprends que la norme doit être respectée, mais cela n'entrave-t-il pas la créativité du programmeur? il existe encore quelques différences dans la façon dont les différents compilateurs suivent les normes. Je peux par exemple écrire un code qui fonctionne, très bon en performance et en vitesse c'est-à-dire tout ce qui compte, mais qui ne suit pas forcément les standards.

Non. La norme indique ce qui est autorisé à faire. S'il n'est pas spécifié, vous êtes dans un territoire de comportement indéfini, puis tous les paris sont désactivés - le programme est libre de faire n'importe quoi.


Puisque vous avez mentionné un exemple spécifique de void main()vs int main(), je peux améliorer ma réponse.

void main()n'est pas une déclaration standard de la fonction principale. Il peut fonctionner sur certains compilateurs via des extensions, mais il dépend de l'implémentation. Même si cela fonctionne, vous devez vérifier s'il fait ce que vous voulez. Le problème est que les développeurs du compilateur peuvent décider de supprimer void main()avec la prochaine version du compilateur, cassant votre application.

D'un autre côté, la norme définit clairement la signature de main as int main()et indique ce qu'elle doit faire.


Par contre, il y a des choses qui ne sont pas définies dans la norme. Ensuite, une autre norme peut s'appliquer (comme par exemple, POSIX). Le meilleur exemple peut être avec l'implémentation de threads en c ++ 03, car les programmes standard c ++ 03 étaient à 1 thread. Dans ce cas, vous êtes obligé d'utiliser une bibliothèque dépendante de la plate-forme, ou quelque chose comme boost .

BЈовић
la source
4
Tout ce qu'un compilateur fait qui n'est pas standard n'est pas un comportement indéfini, les extensions du compilateur sont bien définies en ce sens qu'elles sont déterministes et délibérées. UB ne l'est pas.
Daniel Gratzer
@jozefg La façon dont il a été demandé - il est évident que le PO a pensé à la façon de mettre en œuvre UB. Par exemple, les threads n'étaient pas définis en c ++ 03.
BЈовић
1
@deworde: Le commentaire a été supprimé de la réponse.
Kevin
@jozefg Si un compilateur particulier encapsule toujours des entiers signés, il pourrait être considéré comme une extension de langue non documentée. (Bien sûr, être sans papiers signifie que vous n'avez aucune garantie qu'ils ne suppriment pas l'extension)
user253751
-6

Ne suivez pas les règles SI votre projet concerne des projets spéciaux, par exemple un projet gouvernemental ou militaire, mais vous devez suivre les règles SI vous parlez d'un projet open source ou d'un grand projet avec une équipe distribuée.

Uknown
la source
2
sans explication, cette réponse peut devenir inutile au cas où quelqu'un d'autre posterait une opinion contraire. Par exemple, si quelqu'un publie une réclamation comme "suivez les règles SI votre projet concerne des projets spéciaux, par exemple un projet gouvernemental ou un projet militaire, mais vous n'avez pas besoin de suivre les règles SI vous parlez d'une source ouverte ..." , comment cette réponse aiderait-elle le lecteur à choisir entre deux opinions opposées? Pensez à l' éditer dans une meilleure forme
moucher
2
Uknown: vous seriez surpris d'apprendre combien il y a de normes dans les projets gouvernementaux ...
Deer Hunter