Помните аргумент, что если вы хотите, чтобы ваша веб-страница работала в разных браузерах, то вы должны писать HTML-совместимый стандарт?
То же самое касается компиляторов.
На уровне языка, если ваш код компилируется без предупреждений в GCC с -std = c89 (или -std = c ++ 98 для C ++), -pedantic -Wall, плюс -Wextra, если вы чувствуете себя смелым, и до тех пор, пока вы не использовали ни одно из более явных расширений GNU, разрешенных -pedantic (что трудно сделать случайно), у него есть хорошие шансы работать на большинстве компиляторов C89. C ++ немного менее определен, поскольку вы потенциально полагаетесь на то, насколько полной поддержка целевого компилятора для стандарта.
Написание правильного C89 несколько ограничительно (никакие // комментарии, объявления не должны предшествовать операторам в блоке, никакое встроенное ключевое слово, никакой stdint.h и, следовательно, никаких 64-битных типов и т. Д.), Но это не так уж плохо, как только вы привыкнете Это. Если вам важны только GCC и MSVC, вы можете включить некоторые языковые функции, которые, как вам известно, есть в MSVC. В противном случае вы можете написать свои собственные «языковые абстракции». Например, тот, который определяет «inline» как «inline» в GCC и MSVC / C ++, но «__inline» для MSVC / C. Или MSVC stdint.h достаточно легко найти или написать.
В прошлом я успешно писал переносимый код - я работал в основном на одной платформе для конкретного продукта, используя GCC. Я также написал код для использования на всех платформах, включая Windows XP и Mobile. Я никогда не компилировал его для этих платформ до запуска «тестовой сборки» на сервере сборки, и у меня очень редко возникали проблемы. Я думаю, что мог написать плохой код, который вызвал предупреждение о совместимости 64-битной версии один или два раза.
Программисты Windows, идущие в другую сторону, вызывали случайные проблемы, в основном из-за того, что их компилятор был менее педантичным, чем наш, поэтому мы видели предупреждения, которых они не видели, а не вещи, которые GCC вообще не поддерживал. Но исправление предупреждений означало, что когда код позже использовался в системах с более примитивными компиляторами, он все еще работал.
На уровне библиотеки это намного сложнее. Если вы #include и используете Windows API через windows.h, то, очевидно, это не сработает на Linux, и то же самое, если вы используете KDE с GCC, а затем пытаетесь скомпилировать с MSVC.
Строго говоря, это проблема платформы, а не проблема компилятора, но это то же самое. Если вы хотите написать переносимый код, вам нужен API абстракции ОС, такой как POSIX (или его подмножество), который поддерживают все ваши цели, и вам нужно думать о «переносимости», когда вы пишете его в первую очередь. Взятие кода, интенсивно использующего API для Windows, и попытка заставить его работать в GCC / Linux - это, по сути, полное переписывание AFIAK. Возможно, вам лучше использовать WINE, чем пытаться пересобрать его.