#c #fstream #clang #setw
Вопрос:
Как возможно, чтобы этот код компилировался, даже если я его не включал <iomanip>
?
#include <iostream>
#include <fstream>
int main()
{
std::cout << std::setw(5) << "test" << std::endl;
return 0;
}
Компилируется с:
clang test.cpp
Но без <fstream>
этого выдает ошибку:
test.cpp:5:20: error: no member named 'setw' in namespace 'std'
std::cout << std::setw(5) << "test" << std::endl;
~~~~~^
1 error generated.
На Mac моих друзей это приводит к ошибке в обеих ситуациях.
Комментарии:
1. В вашей системе iomanip включен в заголовок fstream, поэтому он работает, но это определенная реализация, поэтому другой компилятор(-версия) в другой системе может определить fstream без iomanip.
2. Один или оба
iostream
и/илиfstream
могут сами рекурсивно включать несколько файлов заголовков и так далее. Вы можете использовать-H
опциюclang
(илиg
), чтобы точно узнатьiomanip
, откуда включается.
Ответ №1:
Заголовки включают себя внутренне, в зависимости от реализации стандартной библиотеки.
Стандарт не гарантирует, что символ не определен, если вы не включите определенный файл — вместо этого он гарантирует, что символ будет определен, если вы его включите.
В этом случае fstream
заголовок содержит внутренний код, который также имеет определение std::setw
.
Код, компилируемый на вашем компиляторе, является особенностью реализации вашей стандартной библиотеки.
В нашем текущем проекте отсутствующие заголовки являются одной из распространенных причин неудачных сборок (сборка работает в Windows, но не на Mac, или наоборот).
Как правило, включайте указанные заголовки для всего, что вам требуется в вашем коде, даже если код компилируется нормально без включения.
Ответ №2:
Стандартные заголовки C могут включать другие стандартные заголовки, если это удобно для реализации. Ваш <fstream>
в качестве детали реализации включен <iomanip>
, но на Mac он, по-видимому, не был включен.
Правило: Включайте то, что вам нужно, и не полагайтесь на случайное включение. Это не накладывает накладных расходов; все стандартные заголовки могут быть безопасно включены более одного раза.