23

What is the type of the __LINE__ macro in C++?

Cœur
  • 37,241
  • 25
  • 195
  • 267
prabhakaran
  • 5,126
  • 17
  • 71
  • 107
  • its a preprocessor numerical constant. – Anycorn Feb 22 '11 at 08:54
  • @aaa I want to know it's type explicitly, like int,int *,etc. – prabhakaran Feb 22 '11 at 08:56
  • It has no explicit type, because it's preprocessor constant. Every occurence of _ _LINE_ _ is changed to actual value before compilation, so before there are types at all. – Pawel Zubrycki Feb 22 '11 at 09:07
  • @Pawel constants have types too – David Heffernan Feb 22 '11 at 10:47
  • 1
    You still haven't given up abusing operator<< (http://stackoverflow.com/questions/5062699/c-operator-overload-of-needs-const-produces-headache)? What's going to be your next problem: what do I do when the type of `file->open` is the same as the type of `__LINE__` in `check << file->open << __FILE__ << __LINE__ ;` – visitor Feb 22 '11 at 12:14
  • 1
    @David: It has the same type as '2' or any other hardcoded number and it is assumed during usage. In `char line = __ LINE __;` it will be `char` and in `long long line = __ LINE __;` it will be `long long`. Constants are changed to their values before compiling, so before any type exists. – Pawel Zubrycki Feb 22 '11 at 15:59
  • @Pawel What about if the constants are placed in expressions? Or passed to procedures? – David Heffernan Feb 22 '11 at 16:02
  • @David: `const int` is assumed from what I remember. – Pawel Zubrycki Feb 22 '11 at 16:17
  • @Pawel No you are changing your story! ;-) – David Heffernan Feb 22 '11 at 16:19

4 Answers4

22

C++03 §16.8p1:

__LINE__ The line number of the current source line (a decimal constant).

This will either be int, or if INT_MAX (which is allowed to be as little as 32,767) is not big enough (… I won't ask …), then it will be long int. If it would be bigger than LONG_MAX, then you have undefined behavior, which, for once, is not a problem worth worrying about in a file of at least 2,147,483,647 lines (the minimum allowed value for LONG_MAX).

The same section also lists other macros you may be interested in.

Fred Nurk
  • 13,952
  • 4
  • 37
  • 63
  • @prabhakaran: Link to what? The standard or drafts? http://stackoverflow.com/questions/81656/where-do-i-find-the-current-c-or-c-standard-documents – Fred Nurk Feb 22 '11 at 09:07
  • @prabhakaran: `HRESULT` is a typedef, not a seperate and distinct type. In particular, it's a typedef for a numerical type. You can convert 37 to a HRESULT. Now, that 37 could also occur because you had a `__LINE__` macro on line 37. – MSalters Feb 22 '11 at 09:29
  • As you said the __LINE__ macro's type is int. But due to the fact that I had a over loaded function which took long as its argument, my int receiving overloaded function can't get any chance. I forgot the sequence of operator overloading argument match. Now I corrected the functions. Thank you for your reply – prabhakaran Feb 22 '11 at 11:31
  • @MSalters Yes,you are exactly correct, thank you for your correction. My above comment tells the fact exactly. – prabhakaran Feb 22 '11 at 11:33
  • What if I have a source file with 2,147,483,647 lines? (Okay, I'm kidding :P) – Nathan Osman Mar 14 '13 at 22:00
  • 1
    @NathanOsman: You'd need one more, to make 2,147,483,648. However, I'm more worried about #line directive abuse, but more != greatly. – Fred Nurk Nov 13 '13 at 06:43
5

The C++ standard simply has this to say:

__LINE__: The presumed line number (within the current source file) of the current source line (an integer constant).

It does not actually state the type so it's most likely going to be the same type as an unadorned integer would be in your source code which would be an int. The fact that the upper end of the allowed range is 2G - 1 supports that (even though the lower range is 1).

The fact that #line only allows digits (no trailing U to make it unsigned) can also be read to support this.

But, that's only support. I couldn't find a definitive statement within either the C++ or C standards. It just makes sense*a that it will be translated into something like 42 when it goes through the preprocessing phase and that's what the compiler will see, treating it exactly like 42 (an int).


*a: This wouldn't be the first time my common sense was wrong, though :-)

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • The definitive statement for the type of decimal constants is in C++03 §2.13.1p2, which says either int or long int here. – Fred Nurk Feb 22 '11 at 09:12
  • Yes, but it's not necessarily a decimal constant, which is why I was reticent to make a pronouncement. It seems to me that a conforming implementation could convert `__LINE__` into `42U` and still be kosher. I don't have C++03 handy but C++0x where I sourced my stuff from states "integer constant" and that includes U, L, UL, LL and ULL types. – paxdiablo Feb 22 '11 at 09:15
  • 1
    C++03 exactly says "a decimal constant". – Fred Nurk Feb 22 '11 at 09:15
  • @Fred: don't get me wrong, I'm sure you're right and it translates to the banal `42` - it's just my sources were unclear on the matter :-) – paxdiablo Feb 22 '11 at 09:20
  • @Fred: Although "decimal constant" is defined in C++03 only indirectly, by non-normative footnote 21, which refers to C89. In C++ `42` is a *decimal-literal*, and `42U` is not a *decimal-literal*, it's an *integer-literal*. In C `42` is a decimal constant, and `42U` isn't. So the intent is clear, but paxdiablo is right that they messed up the wording in C++03. 16.8/1 should have said "decimal literal", I think, but they've copied C without changing it. If in C++0x they've changed it to "integer constant", that's interesting because presumably that *can* be `42U`, a breaking change. – Steve Jessop Feb 22 '11 at 10:56
  • 1
    @Steve: Don't forget C is a normative reference for C++. But I don't see how what you said changes "but it's not necessarily a decimal constant" => "C++03 exactly says 'a decimal constant'". – Fred Nurk Feb 22 '11 at 13:42
  • 1
    @Fred: it's normative for specific cases where C++ says that what is said in C is true, obvious examples being the contents of most C headers. It is not the case in general that any definition made in C89 applies also to C++. I agree with you that in C++03 it *is* a decimal constant, I'm just pointing out that C++ only very tentatively defines "decimal constant" at all, in a comment stating an intention by comparison with C. I don't think they meant to use the phrase "decimal constant" in C++ at all, but they did and so we must deduce whatever meaning for it we can scrape together. – Steve Jessop Feb 22 '11 at 13:50
1

For general C++ code, see the other answer.

In Visual Studio 2017 (and, I suspect, all other versions) __LINE__ has type long.

I used the following code to discover it:

#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__);
}
anatolyg
  • 26,506
  • 9
  • 60
  • 134
1

C11, footnote 177:

The presumed source file name and line number can be changed by the #line directive.

Note: ISO/IEC Directives, Part 2:

Footnotes to the text of a document are used to give additional contextual information to a specific item in the text. The document shall be usable without the footnotes.

C11, 6.10.4 Line control:

# line digit-sequence new-line

The digit sequence shall not specify zero, nor a number greater than 2147483647.

C11, 5.2.4.2.1 Sizes of integer types <limits.h>:

Their implementation-defined values shall be equal or greater in magnitude (absolute value) to those shown, with the same sign.

maximum value for an object of type long int

LONG_MAX +2147483647 // 2^31 − 1

Hence, I conclude that the maximum value of of __LINE__ is guaranteed to fit into long int.

pmor
  • 5,392
  • 4
  • 17
  • 36