1
votes

Est-il possible de compiler du code C89 sur MS Windows?

J'essaie de travailler avec du code C89 hérité et j'ai du mal à le construire. Mon environnement habituel est Visual Studio, mais cela ne semble prendre en charge que C99, et certaines fonctionnalités de C99 (telles que stdio, etc. n'étant pas nécessairement constantes) cassent le code - beaucoup . Avant de commencer à falsifier le code, je veux écrire des tests, donc je ne romps pas l'ancien comportement, mais je ne peux pas tester les tests, pour ainsi dire, avant de pouvoir construire le code.

Alors, y a-t-il encore un moyen de compiler du code C89 sous Windows?

Edit: Steve Summit a identifié que stdio et ainsi de suite n'a jamais été garanti; c'est juste une caractéristique de certains compilateurs dont mon code hérité dépend, d'une manière assez profondément intégrée. Ma question est donc de savoir s'il existe un compilateur Windows C disponible (de préférence gratuit!) Pour Windows qui prend en charge cette hypothèse. Alternativement, j'ai une installation Ubuntu dans une machine virtuelle, bien que j'aie peu d'expérience de son utilisation - existe-t-il un tel compilateur disponible dans Ubuntu?


12 commentaires

mingw.org est un portage de gcc pour MS, compilez en utilisant gcc -std = c89 -o app.exe source.c


Pouvez-vous montrer un exemple reproductible minimal C89 avec lequel vous rencontrez des problèmes?


Si quoi que ce soit, cela devrait être l'inverse - VS ne prend pas entièrement en charge C99, il peut donc échouer à créer du code à l'aide des fonctionnalités C99, mais il devrait être solide sur le code C89. Quelles erreurs de construction obtenez-vous? Êtes-vous sûr qu'il est compilé en C et non en C ++? Êtes-vous sûr de disposer de tout le code dont vous avez besoin?


MSVC n'est pas un compilateur C99 conforme. Il ne se conforme pas complètement à C89 non plus, mais ses écarts de ce côté sont faibles et quelque peu obscurs. Si la création de code puported-C89 dans MSVS (en mode C, pas en mode C ++) échoue ou produit un exécutable qui se comporte mal, il y a de fortes chances que ce soit le programme qui est cassé, pas le compilateur.


"comme stdio etc. n'étant pas nécessairement constant" Que?


@Lundin Je suppose que cela signifiait que " stdin etc. n'est pas nécessairement constant".


@SteveSummit Mais comment est-ce plus clair? Qu'est-ce qu'un "en-tête constant"?


Je n'ai toujours aucun sens.


La bonne nouvelle: Microsoft a 20 ans de retard sur tous les autres compilateurs C du marché. Ils n'ont encore qu'un support partiel pour C99. Leur compilateur C suit principalement C90. La mauvaise nouvelle: Visual C est mal conforme à tout standard C. Il doit être considéré comme un compilateur C ++ avec un support partiel et bâclé de C sur le côté.


@Lundin voyez la "réponse" que je viens de publier.


Oui, je voulais dire que stdin (et stdout, et stderr) était constant. Et Lundin: le googling que j'ai fait avant de poser la question indiquait que Microsoft attribue stdin, etc., n'étant pas directement constant à l'implémentation C99. Donc 20 ans de retard, c'est encore trop récent.


concernant l'initialisation de stdin, il y a beaucoup de doublons: L'élément d'initialisation d'erreur n'est pas constant , FILE * .. = stdout: l'élément d'initialisation d'erreur n'est pas constant , Initialiser une variable FILE * en C?


3 Réponses :


1
votes

Toutes les versions prises en charge (et même les plus anciennes) de Visual Studio sont parfaitement capables de compiler du code C89. De plus, C99 est rétrocompatible avec les révisions précédentes du langage, donc un compilateur C99 devrait être capable de compiler très bien du code C89.

Bien que vous puissiez recevoir des avertissements, le code devrait se compiler et fonctionner correctement si le code est portable bien sûr.


2 commentaires

"Parfaitement capable" -> "assez capable, peut-être". Mais bon, nous supportons aussi gcc.


Une meilleure option pour un compilateur Windows alternatif est clang, en raison de sa compatibilité binaire avec les bibliothèques MS. :) De plus, je n'ai pas rencontré de code portable C89 que le compilateur MS ne peut pas compiler.



2
votes

[Ce n'est pas vraiment une réponse, mais c'est trop compliqué pour un commentaire.]

Si vous avez du code qui fait des choses comme

#include <stdio.h>
FILE *ifp = stdin;
int main() { ... }

et si le problème que vous rencontrez est une erreur indiquant que stdin n'est pas une constante de compilation adaptée à un initialiseur statique, je pense que vous allez devoir réécrire cet aspect de votre code. Je peux me tromper, mais si je me souviens bien, l'idée que stdin et al. étaient des constantes à la compilation n'a jamais été une garantie, juste une propriété utile des premières implémentations Unix. Ce n'était pas nécessairement vrai pour toutes les anciennes implémentations, donc le «changement» de la norme qui disait explicitement qu'elles n'étaient pas nécessairement constantes n'était pas un changement en soi , mais plutôt, plus ou moins un codification de la divergence des pratiques existantes.

(En d'autres termes, si vous avez un compilateur qui rejette le code, et même s'il a un mode de compatibilité descendante, je serais surpris si le le mode de compatibilité descendante a transformé stdin en une constante de compilation.)


3 commentaires

Il n'y a aucune garantie que stdin soit une constante de compilation dans n'importe quelle version de C et il n'a pas changé depuis C90. Le standard dit simplement qu'il est de type FILE * .


C'est exactement le problème principal que j'obtiens - souvent, sur plusieurs fichiers et enterré dans des structures de données, donc la réécriture n'est probablement pas une bonne idée - je n'ai rien contre lequel tester la réécriture. Il semble que j'ai besoin de trouver un compilateur qui prend en charge cette hypothèse.


@digitig: Certaines plates-formes peuvent utiliser des structures de données pour la gestion des fichiers qui correspondent bien à FILE * , mais qui ne déterminent pas où sera stdin jusqu'à ce que le programme soit exécuté. Bien qu'il soit possible pour une implémentation ciblant une telle plateforme de faire de FILE * un wrapper autour du type interne de l'implémentation, cela signifierait que les modules compilés avec cette implémentation seraient incompatibles avec ceux compilés en utilisant d'autres . Cela peut être un compromis valable à certaines fins, mais pas celui que je m'attendrais particulièrement à ce que les mises en œuvre soutiennent.



3
votes

MSVC est un compilateur C ++ et vient de gagner le support C99 récemment. Auparavant, il ne supportait que C89 avec certaines extensions MS. Pour compiler en mode C89 strict, utilisez l'option / Za . Assurez-vous également d'activer / Tc pour utiliser le mode C

/ Za , / Ze (Désactiver les extensions de langue)

L'option du compilateur / Za désactive et émet des erreurs pour les extensions Microsoft vers C qui ne sont pas compatibles avec ANSI C89 / ISO C90. L'option de compilation obsolète / Ze active les extensions Microsoft. Les extensions Microsoft sont activées par défaut.

Voir Appliquer la norme ANSI C dans Visual Studio 2015

La plupart des autres compilateurs utilisez d'autres options comme -ansi , -std = c90 ou -std = iso9899: 1990


Cependant, s'il s'agit simplement de stdin / stdout qui n'est pas constant lors de l'utilisation dans un statique liste d'initialiseurs, elle n'a donc aucun rapport avec C89 et est en fait un problème XY . L'extrait suivant se compile sans problème en mode C ++ VS2019, donc si vous n'avez pas de conflit possible, compilez simplement le code en mode C ++

FILE* ifp = NULL;
int main()
{
    ifp = stdout;
    fprintf(ifp, "test\n");
    return 0;
}

Sinon, il est facile de résoudre ce problème pour compilez en mode C en déplaçant l'initialisation dans main()

#include <stdio.h>
FILE* ifp = stdout;
int main()
{
    fprintf(ifp, "test\n");
    return 0;
}


2 commentaires

Je ne vois rien de mal à cela, mais cela ne résout pas mon problème, car l'hypothèse selon laquelle les flux standard sont constants est tissée dans tout le code hérité et sera difficile à démêler.


@phuclv existe-t-il quelque part une liste des extensions C99 prises en charge par Visual Studio dans C99?