11

GCC 9 has recently changed the behavior of the __LINE__ directive in some cases. The program below illustrates the change:

#include <stdio.h>
#define expand() __LINE__
int main() {
  printf("%d\n",expand(
                ));
  return 0;
}

Because the macro expand() (which expands to __LINE__) spans more than one line, GCC up to 8.3 (and Clang up to 8.0) considers the number of the last line of the expansion, printing 5. But GCC 9 considers the first line, and prints 4.

(Godbolt link: https://godbolt.org/z/3Nk2al)

The C11 standard is not very precise about the exact behavior of __LINE__, other than:

6.10.8 Predefined macro names

The values of the predefined macros listed in the following subclauses (except for __FILE__ and __LINE__) remain constant throughout the translation unit.

(...)

6.8.10.1 Mandatory macros

The following macro names shall be defined by the implementation:

(...)

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

I assume this means that the exact value is implementation-defined, and therefore one cannot expect its value to remain constant across different compiler versions, or different compilers. Or is there some argument to that effect elsewhere in the standard?

For instance, could one argue that the presumed line number of the current source line should be stable as long as the source itself did not change?

curiousguy
  • 8,038
  • 2
  • 40
  • 58
anol
  • 8,264
  • 3
  • 34
  • 78
  • Interesting. the ways I've used `__LINE__` in the past would be insensitive to this change (I've needed human readability sometimes (and humans are flexible) and a guarantee that the lines numbers reported have the correct *sequence relationships* (which should be preserved under this change)). Is it breaking something for you? – dmckee --- ex-moderator kitten Jun 05 '19 at 17:32
  • Take a look at the preprocessor output (using the `-E` option) to see the results of the macro substitution. With the compiler I'm using, the `printf` ends up as a single line, including the trailing `);` – user3386109 Jun 05 '19 at 17:32
  • 3
    @dmckee It wouldn't be a [tag:language-lawyer] question if it had an actual use case ;-) – Philip Kendall Jun 05 '19 at 18:43
  • @dmckee we have some test oracles that store the preprocessed C code, and software such as Hiredis contains a few `assert`s spanning multiple lines. Because of this change, developers with older GCC versions or using Clang will obtain different oracles, which is how I noticed the difference. – anol Jun 06 '19 at 06:49

1 Answers1

1

While the general case of finding a line number from a specific instruction is hard, i.e. GDB trying to come up with a line number from some code that crashed, the printf __LINE__ instruction is relatively straight forward as the compiler generates the number as a static for a specific location.

The C11 standard itself is just saying that the line number should not change while you are in a macro, i.e. __LINE__ should reflect where you are in a program after the macro has been expanded, not what line of code the macro is located on. This allows you to do things like provide the line number of the callee of your function, by creating a macro that printed the line number and then called your function. For example:

#define f(x) ({ printf("called f(x) at line=%d\n", __LINE__); f__real(x); })

As to the exact line number that is presented, that is compiler dependent and is not apart of any standard. I.e. your example could be rewritten as:

int main() {
  printf("%d\n", 
         __LINE__);
}

and in this case a valid response could be either 2 or 3.

If you are trying to determine the line number dynamically, that is provided through system backtrace libraries. i.e. backtrace() on linux.

Clarus
  • 2,259
  • 16
  • 27