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 宏(与定位宏的标记连接)

C 中的预处理器指令:使用 __LINE__ 的宏

linux __user 宏的含义是啥?

C语言便于调试的宏定义 __FILE____FUNCTION____LINE____VA_ARGS__ 参数使用

linux c 宏定义

宏的使用