[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c

__FILE__: filename from absolute pathname?

pozz

5/6/2011 10:17:00 PM

My compiler defines __FILE__ macro as the source file name under
compilation. I noticed it assigns to the macro the same name passed to
the compiler as the command line argument.

The IDE I'm using always pass to compiler the absolute pathname, so
__FILE__ macro could be very long (C:\DOCUMENTS AND SETTINGS\...).

Also I'm using a custom ASSERT() macro where I print on a display the
__FILE__ and __LINE__ of the statement where the condition of ASSERT()
failed.

This all is good, but my system is embedded with a small Flash memory. I
don't want to consume the memory with very long constant strings derived
from __FILE__ macro.

Is there a preprocessor way to transform the absolute pathname of
__FILE__ (C:\DOCUMENTS AND SETTINGS\...\MAIN.C) to the shorter name of
the file (MAIN.C)?

I think it's impossible, but I'm not an expert, so I ask to you.
7 Answers

Keith Thompson

5/6/2011 11:35:00 PM

0

pozz <pozzugno@gmail.com> writes:
> My compiler defines __FILE__ macro as the source file name under
> compilation. I noticed it assigns to the macro the same name passed to
> the compiler as the command line argument.
>
> The IDE I'm using always pass to compiler the absolute pathname, so
> __FILE__ macro could be very long (C:\DOCUMENTS AND SETTINGS\...).
>
> Also I'm using a custom ASSERT() macro where I print on a display the
> __FILE__ and __LINE__ of the statement where the condition of ASSERT()
> failed.
>
> This all is good, but my system is embedded with a small Flash memory. I
> don't want to consume the memory with very long constant strings derived
> from __FILE__ macro.
>
> Is there a preprocessor way to transform the absolute pathname of
> __FILE__ (C:\DOCUMENTS AND SETTINGS\...\MAIN.C) to the shorter name of
> the file (MAIN.C)?
>
> I think it's impossible, but I'm not an expert, so I ask to you.

I think you're right. But you only need one copy of the full pathname
per source file. For example (this is untested):

static char *FILENAME;

int main(void) /* or whatever your entry point is */
{
const char *source_file_name = __FILE__;
const char *last_backslash = strrch(source_file_name, '\\');
if (last_backslash == NULL) {-
FILENAME = source_file_name;
}
else {
FILENAME = last_backslash + 1;
}
/* ... */
}

Then have your custom ASSERT() refer to FILENAME rather than __FILENAME__.

Or you can compile each source file with "-DFILENAME=<short-filename",
or whatever argument your compiler uses to define a macro.

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.ne...
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Barry Schwarz

5/7/2011 2:46:00 PM

0

On Fri, 06 May 2011 16:35:27 -0700, Keith Thompson <kst-u@mib.org>
wrote:

>pozz <pozzugno@gmail.com> writes:
>> My compiler defines __FILE__ macro as the source file name under
>> compilation. I noticed it assigns to the macro the same name passed to
>> the compiler as the command line argument.
>>
>> The IDE I'm using always pass to compiler the absolute pathname, so
>> __FILE__ macro could be very long (C:\DOCUMENTS AND SETTINGS\...).
>>
>> Also I'm using a custom ASSERT() macro where I print on a display the
>> __FILE__ and __LINE__ of the statement where the condition of ASSERT()
>> failed.
>>
>> This all is good, but my system is embedded with a small Flash memory. I
>> don't want to consume the memory with very long constant strings derived
>> from __FILE__ macro.
>>
>> Is there a preprocessor way to transform the absolute pathname of
>> __FILE__ (C:\DOCUMENTS AND SETTINGS\...\MAIN.C) to the shorter name of
>> the file (MAIN.C)?
>>
>> I think it's impossible, but I'm not an expert, so I ask to you.
>
>I think you're right. But you only need one copy of the full pathname
>per source file. For example (this is untested):
>
>static char *FILENAME;
>
>int main(void) /* or whatever your entry point is */
>{
> const char *source_file_name = __FILE__;

Since __FILE__ must expand to a string literal, (paragraph 6.10.8),
doesn't this require the string literal to be present in the resulting
executable. Once it is there, with static duration, how does the rest
of this code reduce the size of the executable?

It would help if the compiler does not optimize multiple uses of the
same literal to refer to the same static array but the OP would need
to confirm his compiler has that "deficiency". In that case, he would
do just as well to code
static const char FILENAME[] = __FILE__;
at file scope and eliminate the space "wasted" by the extra code, the
now possibly unnecessary inclusion of the strrch function, and the
two pointers.

If his compiler does perform this common optimization, then the OP
needs to explain why he thinks his executable has multiple copies of
the same literal.

> const char *last_backslash = strrch(source_file_name, '\\');
> if (last_backslash == NULL) {-
> FILENAME = source_file_name;
> }
> else {
> FILENAME = last_backslash + 1;
> }
> /* ... */
>}
>
>Then have your custom ASSERT() refer to FILENAME rather than __FILENAME__.
>
>Or you can compile each source file with "-DFILENAME=<short-filename",
>or whatever argument your compiler uses to define a macro.

Only the assert macro is documented to use the __FILE__ macro. Is it
reasonable to infer that no other standard macro does? If other
macros do and if the OP uses any of them, then our efforts here are
doomed. The same is true if the OP uses any non-standard (e.g.,
POSIX) macro that takes advantage of __FILE__.

While we are on the subject of __FILE__, paragraph 6.10.8-3 says that
it is one of two macros that need not remain constant throughout the
translation unit. But __FILE__ is defined to be "the presumed name of
the current source file." Are not source file and translation unit
equivalent (paragraph 5.1.1.1)? Under what conditions could it
change?

--
Remove del for email

Kleuskes & Moos

5/7/2011 5:10:00 PM

0

On May 7, 4:45 pm, Barry Schwarz <schwa...@dqel.com> wrote:
> On Fri, 06 May 2011 16:35:27 -0700, Keith Thompson <ks...@mib.org>
> wrote:
>
>
>
>
>
>
>
>
>
> >pozz <pozzu...@gmail.com> writes:
> >> My compiler defines __FILE__ macro as the source file name under
> >> compilation. I noticed it assigns to the macro the same name passed to
> >> the compiler as the command line argument.
>
> >> The IDE I'm using always pass to compiler the absolute pathname, so
> >> __FILE__ macro could be very long (C:\DOCUMENTS AND SETTINGS\...).
>
> >> Also I'm using a custom ASSERT() macro where I print on a display the
> >> __FILE__ and __LINE__ of the statement where the condition of ASSERT()
> >> failed.
>
> >> This all is good, but my system is embedded with a small Flash memory. I
> >> don't want to consume the memory with very long constant strings derived
> >> from __FILE__ macro.
>
> >> Is there a preprocessor way to transform the absolute pathname of
> >> __FILE__ (C:\DOCUMENTS AND SETTINGS\...\MAIN.C) to the shorter name of
> >> the file (MAIN.C)?
>
> >> I think it's impossible, but I'm not an expert, so I ask to you.
>
> >I think you're right.  But you only need one copy of the full pathname
> >per source file.  For example (this is untested):
>
> >static char *FILENAME;
>
> >int main(void) /* or whatever your entry point is */
> >{
> >    const char *source_file_name = __FILE__;
>
> Since __FILE__ must expand to a string literal, (paragraph 6.10.8),
> doesn't this require the string literal to be present in the resulting
> executable.  Once it is there, with static duration, how does the rest
> of this code reduce the size of the executable?  
>
> It would help if the compiler does not optimize multiple uses of the
> same literal to refer to the same static array but the OP would need
> to confirm his compiler has that "deficiency".  In that case, he would
> do just as well to code
>    static const char FILENAME[] = __FILE__;
> at file scope and eliminate the space "wasted" by the extra code, the
> now possibly unnecessary inclusion of the strrch function,  and the
> two pointers.
>
> If his compiler does perform this common optimization, then the OP
> needs to explain why he thinks his executable has multiple copies of
> the same literal.
>
> >    const char *last_backslash = strrch(source_file_name, '\\');
> >    if (last_backslash == NULL) {-
> >        FILENAME = source_file_name;
> >    }
> >    else {
> >        FILENAME = last_backslash + 1;
> >    }
> >    /* ... */
> >}
>
> >Then have your custom ASSERT() refer to FILENAME rather than __FILENAME__.    
>
> >Or you can compile each source file with "-DFILENAME=<short-filename",
> >or whatever argument your compiler uses to define a macro.
>
> Only the assert macro is documented to use the __FILE__ macro.  Is it
> reasonable to infer that no other standard macro does?  If other
> macros do and if the OP uses any of them, then our efforts here are
> doomed.  The same is true if the OP uses any non-standard (e.g.,
> POSIX) macro that takes advantage of __FILE__.
>
> While we are on the subject of __FILE__, paragraph 6.10.8-3 says that
> it is one of two macros that need not remain constant throughout the
> translation unit.  But __FILE__ is defined to be "the presumed name of
> the current source file."  Are not source file and translation unit
> equivalent (paragraph 5.1.1.1)?  Under what conditions could it
> change?

By employing '#include', if i'm not very much mistaken. That chapter
defines a translation unit as a sourcefile and the files included.

"A source file together with all the headers and source files included
via the preprocessing directive #include is known as a preprocessing
translation unit. After preprocessing, a preprocessing translation
unit is called a translation unit"

And that makes it rather logical for __FILE__ not to be constant over
an entire translation unit.

William Ahern

5/8/2011 4:40:00 AM

0

Barry Schwarz <schwarzb@dqel.com> wrote:
<snip>
> While we are on the subject of __FILE__, paragraph 6.10.8-3 says that
> it is one of two macros that need not remain constant throughout the
> translation unit. But __FILE__ is defined to be "the presumed name of
> the current source file." Are not source file and translation unit
> equivalent (paragraph 5.1.1.1)? Under what conditions could it
> change?

bar.h
const char bar[] = __FILE__;

foo.c
#include <stdio.h>
#include "bar.h"

const char foo[] = __FILE__;

int main(void) {
puts(foo);
puts(bar);
return 0;
}


GCC gives the output:

foo.c
bar.h

clang gives the output:

foo.c
./bar.h

Barry Schwarz

5/8/2011 5:26:00 AM

0

On Sat, 7 May 2011 10:09:49 -0700 (PDT), "Kleuskes & Moos"
<kleuske@xs4all.nl> wrote:

>On May 7, 4:45 pm, Barry Schwarz <schwa...@dqel.com> wrote:

snip

>>
>> While we are on the subject of __FILE__, paragraph 6.10.8-3 says that
>> it is one of two macros that need not remain constant throughout the
>> translation unit.  But __FILE__ is defined to be "the presumed name of
>> the current source file."  Are not source file and translation unit
>> equivalent (paragraph 5.1.1.1)?  Under what conditions could it
>> change?
>
>By employing '#include', if i'm not very much mistaken. That chapter
>defines a translation unit as a sourcefile and the files included.
>
>"A source file together with all the headers and source files included
>via the preprocessing directive #include is known as a preprocessing
>translation unit. After preprocessing, a preprocessing translation
>unit is called a translation unit"
>
>And that makes it rather logical for __FILE__ not to be constant over
>an entire translation unit.

Thanks. I never use #include for code, only for headers, so I didn't
appreciate what they were getting at.

--
Remove del for email

Harald van D?k

5/8/2011 5:43:00 PM

0

On May 8, 7:26 am, Barry Schwarz <schwarzb@dqel.com> wrote:
> On Sat, 7 May 2011 10:09:49 -0700 (PDT), "Kleuskes & Moos"
> <kleuske@xs4all.nl> wrote:
> >On May 7, 4:45 pm, Barry Schwarz <schwa...@dqel.com> wrote:
> >> Under what conditions could it [__FILE__] change?
>
> >By employing '#include', if i'm not very much mistaken. That chapter
> >defines a translation unit as a sourcefile and the files included.
>[...]
> >And that makes it rather logical for __FILE__ not to be constant over
> >an entire translation unit.
>
> Thanks.  I never use #include for code, only for headers, so I didn't
> appreciate what they were getting at.

A realistic scenario for __FILE__ getting expanded in a header file is
an inline function definition containing an assertion. If the assert
triggers, the error message should contain the file containing the
function definition, which is the header file.

Thad Smith

5/12/2011 2:13:00 PM

0

On 5/6/2011 3:16 PM, pozz wrote:
> My compiler defines __FILE__ macro as the source file name under compilation. I
> noticed it assigns to the macro the same name passed to the compiler as the
> command line argument.
>
> The IDE I'm using always pass to compiler the absolute pathname, so __FILE__
> macro could be very long (C:\DOCUMENTS AND SETTINGS\...).

Compile from a makefile or script running in the source directory and only
passing the file name to the compiler?

--
Thad