Недавно попытался найти объективную информацию по поводу того, какого типа "include guard'ы" (в собирательном смысле) сейчас целесообразно использовать в портабельном коде. К сожалению ничего толкового найти не удалось; некоторые исследования были, но они либо используют очень старые версии компиляторов, либо не позволяют сделать объективных выводов, либо рассматривают не все варианты гардов/компиляторов, которые меня интересуют. В общем решил разобраться сам. Надеюсь будет полезно общественности, в особенности тем, кто имеет отношение к стандартам кодирования.
Тестировал 3 варианта:
1. Internal include guard
#ifndef XXX
#define XXX
...
#endif
2. Pragma once
#pragma once
...
3. External include guard (больше для полноты картины)
В дополнение к internal include guard в месте включения файла:
#ifndef XXX
#include "xxx.h"
#endif
Компиляторы:
1. cl: MSVC 2008 (15.00.21022.08)
2. g++ 4.3.2
3. icl: Intel C++ Compiler 11.0.066
Структура заголовочных файлов для тестирования представляет из себя нижнюю диагональную матрицу размера N. Т.е. есть N заголовочных файлов, i-ый файл включает в себя заголовки от i+1 до N. Компилируемый cpp файл включает в себя все заголовки. Если кого интересует, запостю исходный код генератора отдельным постом. Использовал N=100, 195, 400. 195, т.к. g++ на 200 начинает выдавать ошибку компиляции.
Во время тестирования запускал компиляцию 4 раза, потом усреднял последние 3 запуска. Для замера времени использовалась внешняя команда time.
Результаты (все времена в миллисекундах):
cl
g++
icl
Выводы:
Для cl pragma once даёт существенное преимущество перед internal include guard. external include guard обрабатывается ещё лучше.
g++ практически одинаково поддерживает все 3 варианта. Однако internal include guard несколько лучше остальных.
icl одинаково поддерживает internal include guard и pragma once. external include guard даёт некоторое преимущество.
Учитывая результаты и то, что pragma once использовать максимально просто и она поддерживается всеми этими компиляторами, а internal и external include guard дольше писать и есть вероятность ошибок, лично для меня вывод очевиден:
использовать только pragma once.