C++__LINE__宏的类型是啥
Posted
技术标签:
【中文标题】C++__LINE__宏的类型是啥【英文标题】:C++what is the type of the __LINE__ macroC++__LINE__宏的类型是什么 【发布时间】:2011-07-01 20:20:41 【问题描述】:正如您从我的其他问题中看到的那样,你们中的许多人可能已经得到了答案。你能把这些知识分享给我吗?
【问题讨论】:
它是一个预处理器数字常量。 @aaa 我想明确地知道它的类型,比如 int,int *,etc. 它没有明确的类型,因为它是预处理器常量。 _ LINE _ 的每次出现都会在编译之前更改为实际值,因此在没有类型之前。 @Pawel 常量也有类型 你还没有放弃滥用运营商***.com/questions/5062699/…)?你的下一个问题是什么:当file->open
的类型与check << file->open << __FILE__ << __LINE__ ;
中的__LINE__
的类型相同时我该怎么办
【参考方案1】:
C++03 §16.8p1:
__LINE__ 当前源代码行的行号(十进制常量)。
这将是 int,或者如果 INT_MAX(允许小至 32,767)不够大(……我不会问……),那么它将是 long int。如果它比 LONG_MAX 大,那么您有未定义的行为,这在至少 2,147,483,647 行(LONG_MAX 的最小允许值)的文件中不是值得担心的问题。
同一部分还列出了您可能感兴趣的其他宏。
【讨论】:
@prabhakaran:链接到什么?标准还是草案? ***.com/questions/81656/… @prabhakaran:HRESULT
是一个 typedef,而不是一个单独和不同的类型。特别是,它是数字类型的 typedef。您可以将 37 转换为 HRESULT。现在,也可能出现 37,因为您在第 37 行有一个 __LINE__
宏。
正如你所说,LINE 宏的类型是 int。但是由于我有一个重载函数,它的参数需要很长时间,所以我的 int 接收重载函数没有任何机会。我忘记了运算符重载参数匹配的顺序。现在我更正了这些功能。感谢您的回复
@MSalters 是的,您完全正确,感谢您的纠正。我上面的评论准确地说明了事实。
@NathanOsman:你还需要一个,才能赚到 2,147,483,648。但是,我更担心#line 指令滥用,但更多!= 非常。【参考方案2】:
C++ 标准简单地说:
__LINE__
: 当前源行的假定行号(在当前源文件中)(一个整数常量)。
它实际上并没有说明类型,因此它很可能与源代码中未修饰的整数类型相同,即int
。允许范围的上限是 2G - 1
的事实支持这一点(即使下限是 1
)。
#line
只允许数字(没有尾随 U
使其无符号)这一事实也可以被读取以支持这一点。
但是,这只是支持。我在 C++ 或 C 标准中都找不到明确的声明。它只是有意义*a,当它经过预处理阶段时,它会被翻译成类似42
的东西,这就是编译器会看到的东西,就像42
一样对待它(@987654329 @)。
*a:不过,这不是我的常识第一次出错了 :-)
【讨论】:
十进制常量类型的明确声明在 C++03 §2.13.1p2 中,这里说的是 int 或 long int。 是的,但它不一定是十进制常数,这就是我不愿发表声明的原因。在我看来,符合标准的实现可以将__LINE__
转换为42U
并且仍然是犹太洁食。我没有方便的 C++03,但是 C++0x 我从状态“整数常量”中获取我的东西,其中包括 U、L、UL、LL 和 ULL 类型。
C++03 准确地说是“一个十进制常量”。
@Steve:不要忘记 C 是 C++ 的规范参考。但我不明白你所说的如何变化“但它不一定是十进制常量”=>“C++03 准确地说是'一个十进制常量'”。
@Fred:对于 C++ 说 C 中所说的内容是真实的特定情况,这是规范的,明显的例子是大多数 C 头文件的内容。通常情况下,C89 中的任何定义都不适用于 C++。我同意你的观点,在 C++03 中它 is 是一个十进制常量,我只是指出 C++ 只是非常初步地定义了“十进制常量”,在评论中通过比较说明了一个意图我不认为他们打算在 C++ 中使用短语“十进制常量”,但他们确实这样做了,所以我们必须推断出我们可以拼凑起来的任何含义。【参考方案3】:
有关通用 C++ 代码,请参阅the other answer。
在 Visual Studio 2017(我怀疑,所有其他版本)中,__LINE__
的类型为 long
。
我用下面的代码发现了它:
#include <iostream>
#include <typeinfo>
template <typename T>
void print_type(T x)
std::cout << x << " has type " << typeid(x).name();
int main()
print_type(__LINE__);
【讨论】:
【参考方案4】:C11,脚注 177:
可以通过
#line
指令更改假定的源文件名和行号。
注意:ISO/IEC Directives, Part 2:
文档文本的脚注用于为文本中的特定项目提供额外的上下文信息。文档应该可以在没有脚注的情况下使用。
C11, 6.10.4 线路控制:
# line digit-sequence new-line
数字序列不得指定零,也不得指定大于 2147483647 的数字。
C11, 5.2.4.2.1 整数类型的大小 :
它们的实现定义值的大小(绝对值)应等于或大于所示值,符号相同。
long int
类型对象的最大值
LONG_MAX +2147483647 // 2^31 − 1
因此,我得出结论,__LINE__
的最大值保证适合long int
。
【讨论】:
以上是关于C++__LINE__宏的类型是啥的主要内容,如果未能解决你的问题,请参考以下文章
使用 ## 和 __LINE__ 创建 C 宏(与定位宏的标记连接)