如何在不包含 cmath 库的情况下使用 pow
How is it possible to use pow without including cmath library
我正在尝试学习 C++,我正在使用 MS Visual Studio 2019。我有以下代码:
#include <iostream>
int main()
{
std::cout << pow(10, 2);
}
如何在不包含cmath
的情况下编译和运行不出错?在解决方案中只有一个包含上述代码的文件。
更新:关注@Pete Becker 的评论,我更正我的回答:
您的代码格式不正确,因此会调用所谓的未定义行为,而不是实现定义的行为。
但是这个结论并不完全安全,因为我们在这里进入了语言律师的部分。
未定义行为 (UB) 定义为
behavior for which this International Standard imposes no requirements
which usually means: Don't try to reason about this code and never use it.
问题是,C++ 是否对您的代码指定了要求,即您的代码 是 well-formed 程序 吗?那么这将是指定的行为(通常的行为),未指定的行为,甚至是实现定义的行为的资格。但是在 20.5.2.2 Headers [using.headers] 中,C++ 标准说
A translation unit shall include a header only outside of any declaration or definition, and shall include the
header lexically before the first reference in that translation unit to any of the entities declared in that header.
No diagnostic is required.
根据 Difference between Undefined Behavior and Ill-formed, no diagnostic message required 这将暗示未定义的行为,即使它没有直接违反 6.2 One-definition 规则 ,该规则必须被违反在你的情况下是一个 ill-formed 程序,但是作为链接问题的答案已经说明这个规则默认为未定义的行为,如果没有一个定义,我们这里有一个错误的程序。
旧部分:简单但不令人满意的答案:所谓的实现定义行为。 Microsoft Visual C++ 编译器及其 header 可以自由地相互包含,可能 MSVC iostream
header 已经以至少可传递的方式包含 cmath
如果不是直接的话.
如果您尝试使用 gcc 或 clang 编译相同的代码,乐趣就开始了。突然丢失的包含至少是我的代码中最常见的可移植错误。
如果您实际上包含标准规定的每个 header,即包含您正在使用的内容的定义,您将获得所谓的 可移植代码,意思是代码无论使用 MSVC/Visual Studio 或 gcc 或 clang 或任何其他符合标准的编译器,都会编译并执行相同的操作。
How is possible in C++ to use pow without include cmath library
通过包含另一个 header,其中包含 <math.h>
header。
不能保证标准库 header 一般不会包含其他 header,也不保证 <iostream>
不会特别包含 <cmath>
.也不能保证 <iostream>
将包含 header,因此当使用另一个标准库实现或相同版本的另一个版本时,该程序可能无法编译。
总之:永远不要依赖这种传递包含。始终直接包含声明所依赖的所有 header,除非传递性包含已明确说明(例如,<ios>
保证包含 <iosfwd>
)。您不能将编译成功作为您已提供所有必需的直接包含的证明。
我正在尝试学习 C++,我正在使用 MS Visual Studio 2019。我有以下代码:
#include <iostream>
int main()
{
std::cout << pow(10, 2);
}
如何在不包含cmath
的情况下编译和运行不出错?在解决方案中只有一个包含上述代码的文件。
更新:关注@Pete Becker 的评论,我更正我的回答:
您的代码格式不正确,因此会调用所谓的未定义行为,而不是实现定义的行为。
但是这个结论并不完全安全,因为我们在这里进入了语言律师的部分。
未定义行为 (UB) 定义为
behavior for which this International Standard imposes no requirements which usually means: Don't try to reason about this code and never use it.
问题是,C++ 是否对您的代码指定了要求,即您的代码 是 well-formed 程序 吗?那么这将是指定的行为(通常的行为),未指定的行为,甚至是实现定义的行为的资格。但是在 20.5.2.2 Headers [using.headers] 中,C++ 标准说
A translation unit shall include a header only outside of any declaration or definition, and shall include the header lexically before the first reference in that translation unit to any of the entities declared in that header. No diagnostic is required.
根据 Difference between Undefined Behavior and Ill-formed, no diagnostic message required 这将暗示未定义的行为,即使它没有直接违反 6.2 One-definition 规则 ,该规则必须被违反在你的情况下是一个 ill-formed 程序,但是作为链接问题的答案已经说明这个规则默认为未定义的行为,如果没有一个定义,我们这里有一个错误的程序。
旧部分:简单但不令人满意的答案:所谓的实现定义行为。 Microsoft Visual C++ 编译器及其 header 可以自由地相互包含,可能 MSVC iostream
header 已经以至少可传递的方式包含 cmath
如果不是直接的话.
如果您尝试使用 gcc 或 clang 编译相同的代码,乐趣就开始了。突然丢失的包含至少是我的代码中最常见的可移植错误。
如果您实际上包含标准规定的每个 header,即包含您正在使用的内容的定义,您将获得所谓的 可移植代码,意思是代码无论使用 MSVC/Visual Studio 或 gcc 或 clang 或任何其他符合标准的编译器,都会编译并执行相同的操作。
How is possible in C++ to use pow without include cmath library
通过包含另一个 header,其中包含 <math.h>
header。
不能保证标准库 header 一般不会包含其他 header,也不保证 <iostream>
不会特别包含 <cmath>
.也不能保证 <iostream>
将包含 header,因此当使用另一个标准库实现或相同版本的另一个版本时,该程序可能无法编译。
总之:永远不要依赖这种传递包含。始终直接包含声明所依赖的所有 header,除非传递性包含已明确说明(例如,<ios>
保证包含 <iosfwd>
)。您不能将编译成功作为您已提供所有必需的直接包含的证明。