View previous topic :: View next topic |
Author |
Message |
future
Joined: 14 May 2004 Posts: 330
|
Preprocessor __LINE__ broken in V5 |
Posted: Tue Aug 13, 2019 10:35 pm |
|
|
Hello everybody,
I am trying to make this macro work on version 5. Version 4.100+ preprocesses it correctly, but the later compilers do not.
There is nothing about it in the recent software changes so I wonder if anybody else is using it.
Code: |
#define MT_LABEL_HELP(line) _l##line##_
#define MT_LABEL MT_LABEL_HELP(__LINE__)
void main() {
void *plabel = label_address(MT_LABEL);
MT_LABEL: ;
} |
Thank you. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Wed Aug 14, 2019 1:38 am |
|
|
Er. __LINE__ is not broken, but what you are trying to do is.
__LINE__ returns the line number. How can this have a 'label_address'?.
Label_address requires a C label. Something inside the code. The line number
is not a C label.
If it worked in the past, it was then 'wrong'.
A line number is not an 'address' in the code, it is a simple number.
If you want the line number in the code then simply:
int32 line_number=(__LINE__);
will give this.
If you want to know where a particular line is in processor space, then
simply put a label there.
marker:
Will be a label at the address in the code where it is placed. This can
then be used as an address as you show. |
|
|
future
Joined: 14 May 2004 Posts: 330
|
|
Posted: Thu Aug 15, 2019 9:46 pm |
|
|
Actually the idea is to construct a label like: "_l34_:"
Code: |
#define MT_LABEL_HELP(line) _l##line##_
#define MT_LABEL MT_LABEL_HELP(__LINE__) |
It uses the concatenation operator to create the label at compile time.
V5 is not working it out.
Code: |
31 void main() {
32 do {
33 void *plabel = label_address(MT_LABEL);
34 MT_LABEL: ;
35 goto_address(plabel);
36 } while(0);
37 } |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Thu Aug 15, 2019 11:18 pm |
|
|
Problem is that when you access MT_LABEL in the pointer declaration
line, it tries to construct a line number 'inside' the line where you declare
the pointer, not access the label constructed further down the code.
Do it like this:
Code: |
#define MT_LABEL_HELP(line) _l##line##_ //concatenate
#define MT_LABELCAT(x) MT_LABEL_HELP(x) //expand
#define MT_LABEL MT_LABELCAT(__LINE__) //call
void main() {
MT_LABEL: void *plabel = label_address(MT_LABEL);
}
|
Then you declare plabel to equal MT_LABEL in the same line that MT_LABEL
is created. So the declaration then works. Done a line apart, the expansion
gives a different line number to the two locations, so it can't work....
V5 is a lot more careful than V4 on things like this. However it would have
expanded 'wrong' on any compiler I can think of....
Just went back and tried the original syntax on two V4 compilers (4.141, and
4.104), and it failed on both. However it does incorrectly expand the
actual __LINE__ into the line number. Incorrectly, since in the C
preprocessor this should only happen when it is passed into another
define (as I show).
It is awful, but this is the way that the C preprocessor works..... |
|
|
future
Joined: 14 May 2004 Posts: 330
|
|
Posted: Fri Aug 16, 2019 6:41 pm |
|
|
Ttelmah,
Thank you very much for the hint. The extra expand step fixed for V5 while V4 did without it.
I actually made a typo: An extra '\' is part of the original macro.
Code: |
31 void main() {
32 do {
33 void *plabel = label_address(MT_LABEL); \
34 MT_LABEL: ;
35 goto_address(plabel);
36 } while(0);
37 }
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Sat Aug 17, 2019 12:42 am |
|
|
I remember hitting a similar problem when V5 first launched, but then did
some research and realised that V4 was letting an incorrect syntax work...
Have fun... |
|
|
|