__FILE__ expansion

Go To Last Post
13 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Is there anyway to get __FILE__ to be expanded when a macro is created vs when the macro is referenced.

For example suppose I have

#define HNAME __FILE__

In a header file that is included in a .c file.

If I access HNAME, in the .c file the __FILE__ will get expanded to be the name of the .c file rather than the .h file.

Is there anyway around this?
I've tried several things including trying to use argument prescan but haven't been able to find anything that works.

--- bill

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ehm, when you are editing the particular header, typing the HNAME macro definition, you know the name of the file you are currently editing, don't you?

So what is wrong with

#define HNAME typing_the_name_of_the_file_I_am_just_editing

?

Stealing Proteus doesn't make you an engineer.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm not sure , but it would seem logical that _FILE_ expands to the file being compiled (processed) ...
So in my mind the .c suffix makes sense.

But i don't know if there is a "trick" to process the .h file :-)

/Bingo

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I merely boiled the usage case down to the simplest terms.

In the real situation, there are multiple header files that are part of configuring a more complex system.
End users (sometimes much less technical users) are doing the editing (not me) and they can create custom header configuration files
by potentially copying a template header file and then modifying that version.
When things go haywire there are some diagnostics that can be run that can report the configuration
and it would be nice to be able to report the name of the users configuration header file.
This ensures that there would be no confusion between the file really being used and the file the user might think is being used.

If __FILE__ worked then they wouldn't have to modify anything and the name of their header file could be reported.

I know I can do it with a static string array/pointer but I was trying to do it with a define.

So for example if I put this in the header:

char *HNAME = __FILE__;

Then you get the name of the header file.

I may have to resort to using a static string
as I'd like to avoid manually edited define strings.

--- bill

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ArnoldB wrote:
Ehm, when you are editing the particular header, typing the HNAME macro definition, you know the name of the file you are currently editing, don't you?

So what is wrong with

#define HNAME typing_the_name_of_the_file_I_am_just_editing

?

Tipos and renames.
Computers are so much more reliable than humans at tedious work.
Some source code control systems will do stuff like that.
Another possibility is to give the users a build system
that will edit a header wherever it finds a __PHILE__.

Iluvatar is the better part of Valar.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

skeeve wrote:
Tipos
:-?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

In a header file that is included in a .c file.

If I access HNAME, in the .c file the __FILE__ will get expanded to be the name of the .c file rather than the .h file.

Is there anyway around this?


That is an interesting question, given your aim(s) for its use. My draft of standard C says

Quote:
6.10.8 Predefined macro names
1 The following macro names151) shall be defined by the implementation:
...
_ _FILE_ _ The presumed name of the current source file (a character string literal).152)

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


[full disclosure: I have no idea what the "right" way would be]

If it is working as you have said, then I'm pre-processing and I get to a point where I want to indicate that things are in conflict, and trap the location.

Note 152) says "152) The presumed source file name and line number can be changed by the #line directive." so maybe you could do something with that.

NB: I tried it in a different toolchain, and got the name of the .h file.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:
NB: I tried it in a different toolchain, and got the name of the .h file.
I'm surprised.
I thought the standard was fairly definite about when macros were expanded.
Otherwise, the # and ## rules would have been even more of a mess.

Iluvatar is the better part of Valar.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

I thought the standard was fairly definite about when macros were expanded.

[like I said, I have no idea what is "right"]
Check this link, and associated pages:
http://www.delorie.com/gnu/docs/...
Quote:
An `#include' directive changes the expansions of __FILE__ and __LINE__ to correspond to the included file. At the end of that file, when processing resumes on the input file that contained the `#include' directive, the expansions of __FILE__ and __LINE__ revert to the values they had before the `#include' (but __LINE__ is then incremented by one as processing moves to the line after the `#include').

And a close-by page uses header files as an example, but I can't find it right now.

Cliff has lotsa toolchains loaded... ;)

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:
Quote:

I thought the standard was fairly definite about when macros were expanded.

[like I said, I have no idea what is "right"]
Check this link, and associated pages:
http://www.delorie.com/gnu/docs/...
Quote:
An `#include' directive changes the expansions of __FILE__ and __LINE__ to correspond to the included file. At the end of that file, when processing resumes on the input file that contained the `#include' directive, the expansions of __FILE__ and __LINE__ revert to the values they had before the `#include' (but __LINE__ is then incremented by one as processing moves to the line after the `#include').

And a close-by page uses header files as an example, but I can't find it right now.
My understanding is that the key word is "expands": nothing expands in a #define.
In the header file,
static char file[]=__FILE__;

would give the name of the header file.

foo.h
#define _file_ __FILE__

bar.c
#include "foo.h"
...
static char file[]=_file_;

would not, because no expansion would occur until _file_ was used outside a #define.

Iluvatar is the better part of Valar.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

skeeve wrote:
My understanding is that the key word is "expands": nothing expands in a #define.
In the header file,
static char file[]=__FILE__;

would give the name of the header file.

foo.h
#define _file_ __FILE__

bar.c
#include "foo.h"
...
static char file[]=_file_;

would not, because no expansion would occur until _file_ was used outside a #define.

That is the behavior I see.
I think that is normally the way you want it to work.
I just had this odd case where I wanted to expand it before the macro was referenced.

Even argument prescan waits until the macro is used to expand all the macros.

I've since moved on to a less automated method.

--- bill

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

skeeve wrote:
My understanding is that the key word is "expands": nothing expands in a #define.

No.
C99 par.6.10.3 verse 9 wrote:
A preprocessing directive of the form
# define identifier replacement-list new-line
defines an object-like macro that causes each subsequent instance of the macro name149)
to be replaced by the replacement list of preprocessing tokens that constitute the
remainder of the directive. The replacement list is then rescanned for more macro names
as specified below.

Which clearly states that the instance of occurence of a macro name within an other #define should be replaced by the replacement list etc.

That gcc does it in a different way (claiming it's equivalent) is IMHO not bad, just potentially flawed in this corner case.

Also note, that __FILE__ is a macro name, so it should be expanded wherever other macros are expanded.

Of course it still might be up to the implementation how they interpret "the presumed name of the current source file" (definition of __FILE__) in light of how #include is defined, but it should be at least consistent.

JW

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

wek wrote:
skeeve wrote:
My understanding is that the key word is "expands": nothing expands in a #define.

No.
C99 par.6.10.3 verse 9 wrote:
A preprocessing directive of the form
# define identifier replacement-list new-line
defines an object-like macro that causes each subsequent instance of the macro name149)
to be replaced by the replacement list of preprocessing tokens that constitute the
remainder of the directive. The replacement list is then rescanned for more macro names
as specified below.

Which clearly states that the instance of occurence of a macro name within an other #define should be replaced by the replacement list etc.
That is how I would take it also.
I think that the C99 authors didn't mean what they wrote.
It leads to conflicts with the rationale document.
Under the quoted rule, paste and xpaste would be identical:
#define xpaste(a, b) a ## b
#define  paste(a, b) xpaste(a, b)

They are not.
Also the rationale document gives an example of an ambiguity that would not be ambiguous:

#define f(a) a*g
#define g(a) f(a)
    // ? same as #define g(a) a*g
f(2)(9) ;
//  --> 2*g(9) --> 2*f(9) --> ambiguous
//? --> 2*g(9) --> 2*9*g

Quote:
That gcc does it in a different way (claiming it's equivalent) is IMHO not bad, just potentially flawed in this corner case.
I wouldn't call this a corner case.
Quote:
Also note, that __FILE__ is a macro name, so it should be expanded wherever other macros are expanded.

Of course it still might be up to the implementation how they interpret "the presumed name of the current source file" (definition of __FILE__) in light of how #include is defined, but it should be at least consistent.

I suspect the issue is with the meaning of "subsequent instance".

Iluvatar is the better part of Valar.