[N4519] Source-Code Information Capture - What is the file_name?

162 views
Skip to first unread message

Stephen Kelly

unread,
Jul 12, 2015, 6:23:05 AM7/12/15
to std-dis...@isocpp.org, rwdo...@gmail.com


Hello,


http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4519.pdf


proposes to add a source_location class which has a file_name member. This will give access to the 'presumed name' of the current source file.


What is a 'presumed name'? I realize it is something that can be changed by the user (http://eel.is/c++draft/cpp.predefined#footnote-158) but I don't know what it is before the user changes/overrides it. Is there a reference for that?


As far as this file_name would replace the FILE macro, it would be good to solve the problems that that has.


Consider this:



stephen@hal:/tmp/filemacro-build$ g++ --version

g++ (Ubuntu 5.1.1-4ubuntu12) 5.1.1 20150504

Copyright (C) 2015 Free Software Foundation, Inc.


stephen@hal:/tmp/filemacro$ tree

.

├── dir1

│   └── dir1.h

├── dir2

│   └── dir2.h

├── header.h

└── main.cpp


stephen@hal:/tmp/filemacro$ find . -type f -print -exec cat {} \;

./main.cpp


#include <iostream>


#include "header.h"

#include "dir1.h"

#include "dir2.h"


int main()

{

std::cout << __FILE__ << std::endl;

doHeader();

doDir1();

doDir2();

return 0;

}


./dir1/dir1.h


#include <iostream>


void doDir1()

{

std::cout << __FILE__ << std::endl;

}


./header.h


#include <iostream>


void doHeader()

{

std::cout << __FILE__ << std::endl;

}


./dir2/dir2.h


#include <iostream>


void doDir2()

{

std::cout << __FILE__ << std::endl;

}



stephen@hal:/tmp/filemacro$ cd ../filemacro-build/


stephen@hal:/tmp/filemacro-build$ g++ -I ../filemacro/dir1/ -I /tmp/filemacro/dir2 ../filemacro/main.cpp


stephen@hal:/tmp/filemacro-build$ ./a.out

../filemacro/main.cpp

../filemacro/header.h

../filemacro/dir1/dir1.h

/tmp/filemacro/dir2/dir2.h


stephen@hal:/tmp/filemacro-build$ g++ -I ../filemacro/dir1/ -I /tmp/filemacro/dir2 /tmp/filemacro/main.cpp


stephen@hal:/tmp/filemacro-build$ ./a.out

/tmp/filemacro/main.cpp

/tmp/filemacro/header.h

../filemacro/dir1/dir1.h

/tmp/filemacro/dir2/dir2.h




1) The __FILE__ macro expands to a relative or absolute path depending on whether the file being compiled is specified to the compiler as a relative or absolute path.

2) The __FILE__ macro in an included file expands to either a relative or absolute path depending on whether the include path is specified as a relative or absolute path.

3) In either case, the build-time path is somehow relevant, either by being present in full, or by being implicitly present in the relative part.

4) The user here has a concept of 'the source root of my project', which is the directory where the main.cpp is here. They may in reality want to get paths relative to that.

5) Even if users could get paths relative to 'the source root of my project', the file layout implied by that in the source tree is not necessarily related to the installed layout (eg into an include/ direcory). There may be multiple competing use-cases here. I would like to find out what they are and whether there is a design for source_location which satisfies all of them.


This post is motivated by this thread on the cmake mailing list:


http://thread.gmane.org/gmane.comp.programming.tools.cmake.devel/12173


Thanks,


Steve.



David Krauss

unread,
Jul 12, 2015, 7:32:42 AM7/12/15
to std-dis...@isocpp.org
On 2015–07–12, at 6:23 PM, Stephen Kelly <stev...@gmail.com> wrote:

What is a 'presumed name'? I realize it is
something that can be changed by the user (http://eel.is/c++draft/cpp.predefined#footnote-158) but I don't know what it is before the user changes/overrides it. Is there a reference for that?

It’s implementation-defined, as is everything to do with pathnames of source files.

The only references you’ll find are from the vendors.

1) The __FILE__ macro expands to a relative or
absolute path depending on whether the file being compiled is specified to the compiler as a relative or absolute path.
2) The __FILE__ macro in an included file expands to either a relative or absolute path depending on whether the include path is specified as a relative or absolute path.
3) In either case, the build-time path is somehow relevant, either by being present in full, or by being implicitly present in the relative part.

Most implementations do their best to minimize ambiguity in the value of __FILE__, while avoiding the inconvenience of absolute paths.

4) The user here has a concept of 'the source root of my project', which is the directory where the main.cpp is here. They may in reality want to get paths relative to that.

Your compiler already provides paths relative to one common, user-defined point: the working directory at its invocation. It sounds like the solution is to change directories to src/ before invoking the compiler.

With compile-time constexpr string processing, you could probably define some “pathname arithmetic” to adjust __FILE__ strings to your liking.

5) Even if users could get paths relative to 'the source root of my project', the file layout implied by that in the source tree is not necessarily related to the installed layout (eg into an include/ direcory). There may be multiple competing use-cases here. I would like to find out what they are and whether there is a design for source_location which satisfies all of them.

source_location simply provides a way to get __FILE__ without naming a macro at the given file location. It does not attempt to standardize build systems.

There does seem to be lingering ambiguity in N4519. The values returned are, at best, implementation-defined. It only provides minimal conditions for which the implementation must document some behavior.


Ah, this user chose a simple form of constexpr string processing.

To get special refinement of __FILE__ values, it sounds like you have three choices: fix your own build system so cmake doesn’t directly invoke the compiler, fix cmake, or fix all the compilers compatible with cmake.

Bo Persson

unread,
Jul 12, 2015, 9:47:19 AM7/12/15
to std-dis...@isocpp.org
On 2015-07-12 12:23, Stephen Kelly wrote:
>
> Hello,
>
>
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4519.pdf
>
>
> proposes to add a source_location class which has a file_name member.
> This will give access to the 'presumed name' of the current source file.
>
>
> What is a 'presumed name'? I realize it is something that can be changed
> by the user (http://eel.is/c++draft/cpp.predefined#footnote-158) but I
> don't know what it is before the user changes/overrides it. Is there a
> reference for that?
>
>
> As far as this file_name would replace the FILE macro, it would be good
> to solve the problems that that has.
>
>
> Consider this:

[ lots of examples ]

>
> 1) The __FILE__ macro expands to a relative or absolute path depending
> on whether the file being compiled is specified to the compiler as a
> relative or absolute path.
>
> 2) The __FILE__ macro in an included file expands to either a relative
> or absolute path depending on whether the include path is specified as a
> relative or absolute path.
>
> 3) In either case, the build-time path is somehow relevant, either by
> being present in full, or by being implicitly present in the relative part.
>
> 4) The user here has a concept of 'the source root of my project', which
> is the directory where the main.cpp is here. They may in reality want to
> get paths relative to that.
>
> 5) Even if users could get paths relative to 'the source root of my
> project', the file layout implied by that in the source tree is not
> necessarily related to the installed layout (eg into an include/
> direcory). There may be multiple competing use-cases here. I would like
> to find out what they are and whether there is a design for
> source_location which satisfies all of them.
>
>

You are assuming that the system HAS relative or absolute paths. Or is
using paths at all. Some systems, like IBM z/OS, does not, but it is
still used for lots of heavy development.

It's not a good idea for a language standard to specify things that we
know cannot be implemented on some systems.


This reminds me of the attempts to standardize #pragma once as a
replacement for include guards. It is relatively easy to specify if a
header file is unique on a Linux or Windows system, but almost
impossible to specify what a remote mount holds (or if it is mounted
more than once on different paths (again assuming paths, of course :-)).

I think you will have a similar problem here, unless you go for
"implementation defined" and are satisfied with what your implementation
offers.



Bo Persson





Stephen Kelly

unread,
Jul 15, 2015, 4:59:02 PM7/15/15
to std-dis...@isocpp.org
Bo Persson wrote:

> You are assuming that the system HAS relative or absolute paths. Or is
> using paths at all. Some systems, like IBM z/OS, does not, but it is
> still used for lots of heavy development.

Ok.

> I think you will have a similar problem here, unless you go for
> "implementation defined" and are satisfied with what your implementation
> offers.

I don't know what you mean here.

Even within a single implementation (I tested with GCC), the FILE macro is
not useful at compile time because it can contain anything. A runtime test
is required to determine whether it is absolute or relative for example, and
then externally supplied information can be used at runtime to make sense of
relative paths.

I assume source_location::file_name would be similarly 'meaningless'
content at compile-time, yet it is constexpr. Is there any feature-
usefulness to it being constexpr?

There might be scope for adding additional information to source_location
though, with other members, right?

Thanks,

Steve.

Stephen Kelly

unread,
Jul 15, 2015, 5:12:58 PM7/15/15
to std-dis...@isocpp.org
David Krauss wrote:
>> On 2015–07–12, at 6:23 PM, Stephen Kelly <stev...@gmail.com> wrote:
>>
>> What is a 'presumed name'? I realize it is
>> something that can be changed by the user
>> (http://eel.is/c++draft/cpp.predefined#footnote-158
>> <http://eel.is/c++draft/cpp.predefined#footnote-158>) but I don't
>> know what it is before the user changes/overrides it. Is there a
>> reference for that?
>
> It’s implementation-defined, as is everything to do with pathnames of
> source files.

Ok.

>> 1) The __FILE__ macro expands to a relative or
>> absolute path depending on whether the file being compiled is
>> specified to the compiler as a relative or absolute path.
>> 2) The __FILE__ macro in an included file
>> expands to either a relative or absolute path depending on whether
>> the include path is specified as a relative or absolute path.
>> 3) In either case, the build-time path is
>> somehow relevant, either by being present in full, or by being
>> implicitly present in the relative part.
>
> Most implementations do their best to minimize ambiguity in the value of
> __FILE__, while avoiding the inconvenience of absolute paths.

Yes. I don't suggest absolute paths are a solution to the problems here. I
am not proposing any solutions at all yet, in fact.

I'm trying to find out whether there is any point in putting any energy into
designing with these problems in mind, such as adding extra information to
the source_location.

What do you think?

Obviously, apart from the work of doing such design, the other work is
getting a valid starting point which is credible on this mailing list.

So far the message I'm getting is 'don't even try to discuss it' :).

>> 4) The user here has a concept of 'the source
>> root of my project', which is the directory where the main.cpp is
>> here. They may in reality want to get paths relative to that.
>
> Your compiler already provides paths relative to one common, user-defined
> point: the working directory at its invocation. It sounds like the
> solution is to change directories to src/ before invoking the compiler.

That was discussed on the thread I linked.

> With compile-time constexpr string processing, you could probably define
> some “pathname arithmetic” to adjust __FILE__ strings to your liking.

That was also discussed in the thread I linked. It's a short thread if you
would to take a look. It provides essential context for this discussion and
the mail I posted.

My original mail can not be understood if you do not read the thread I
linked.

>> 5) Even if users could get paths relative to
>> 'the source root of my project', the file layout implied by that
>> in the source tree is not necessarily related to the installed
>> layout (eg into an include/ direcory). There may be multiple
>> competing use-cases here. I would like to find out what they are
>> and whether there is a design for source_location which satisfies
>> all of them.
>
> source_location simply provides a way to get __FILE__ without naming a
> macro at the given file location. It does not attempt to standardize build
> systems.

I do not attempt to 'standardize buildsystems', whatever that means, as far
as I know.

The points I numbered 1..5 relate to FILE not being useful (at compile time
at least) because it has no semantics, and there is no additional
information going along with it to make it useful.

This thread is about whether there is any point in considering an attempt at
addressing that.

What you specifically quoted is about wondering what the use-cases for FILE
and source_location are. Is that not-on-topic somehow?

> There does seem to be lingering ambiguity in N4519.

That is what motivated starting this thread.

> The values returned
> are, at best, implementation-defined. It only provides minimal conditions
> for which the implementation must document some behavior.
>
>>
http://thread.gmane.org/gmane.comp.programming.tools.cmake.devel/12173
>>
<http://thread.gmane.org/gmane.comp.programming.tools.cmake.devel/12173>
> Ah, this user chose a simple form of constexpr string processing.

Ok, perhaps you read the linked thread after writing your mail?!? Is that
what happened? (I have to wonder why?)

> To get special refinement of __FILE__ values, it sounds like you have
> three choices: fix your own build system so cmake doesn’t directly invoke
> the compiler, fix cmake, or fix all the compilers compatible with cmake.

I think you're missing something, and I'm guessing you have never used
cmake.

I suggest leaving cmake out of the discussion. I provided the link for
context and to indicate what motivated starting the thread here in the first
place. If it causes confusion, then ignore cmake.

In the original mail, I deliberately posted direct invocations of a widely
used compiler specifically to avoid that kind of confusion.

Thanks for your response,

Steve.

Nevin Liber

unread,
Jul 15, 2015, 6:30:28 PM7/15/15
to std-dis...@isocpp.org

On 15 July 2015 at 15:58, Stephen Kelly <stev...@gmail.com> wrote:
I assume source_location::file_name would be similarly  'meaningless'
content at compile-time, yet it is constexpr. Is there any feature-
usefulness to it being constexpr?

It isn't meaningless; it just doesn't have a portable meaning.  Is there any reason for it not to be constexpr?

That being said, given that string_view cannot by design necessarily be constructed in a constexpr context even though it has a constexpr constructor, it probably isn't all that useful for file_name to be constexpr.
--
 Nevin ":-)" Liber  <mailto:ne...@eviloverlord.com(847) 691-1404

David Krauss

unread,
Jul 16, 2015, 12:45:07 AM7/16/15
to std-dis...@isocpp.org
On 2015–07–16, at 5:12 AM, Stephen Kelly <stev...@gmail.com> wrote:

I'm trying to find out whether there is any point in putting any energy into
designing with these problems in mind, such as adding extra information to
the source_location.

What do you think?

The purpose of __FILE__ is to help with debugging. It’s widely used for that, with few complaints. source_location is supposed to be the same.

Using it for logging is a little bit of a hack. Logs are supposed to be read by end-users. It’s obnoxious for a software module vendor to change the logging format, because that breaks scripts that filter logs. Designing a platform library to tie the output format of the modules to the names of their source files, and the division of functionality between implementation files and headers, seems like a really bad idea.

My original mail can not be understood if you do not read the thread I
linked.

I did read the thread. It doesn’t really illuminate the use case.

I do not attempt to 'standardize buildsystems', whatever that means, as far
as I know.

Well, the stated problem is that cmake doesn’t use relative paths as most equivalent tools do. The solution you proposed to this list was essentially to have the compiler process paths before opening them. Let’s say, for the sake of argument, that the “build system” ends and the “compiler” begins when the file is opened. In any case, that’s the scope of behavior addressed by the ISO standard.

The points I numbered 1..5 relate to FILE not being useful (at compile time
at least) because it has no semantics, and there is no additional
information going along with it to make it useful.

This thread is about whether there is any point in considering an attempt at
addressing that.

What you specifically quoted is about wondering what the use-cases for FILE
and source_location are. Is that not-on-topic somehow?

It’s used for debugging: the assert macro and similar user-defined facilities. There’s currently an effort to let templates generate their own diagnostic messages, so for example a __FILE__ string from a header could be stored in a class and later appear in a diagnostic message from a different file.

There does seem to be lingering ambiguity in N4519.

That is what motivated starting this thread.

You’re concerned with nailing down the format of __FILE__ for a given source location. The ambiguity in N4519 is that a source_location constructor invocation might refer to an unexpected source location.

Ok, perhaps you read the linked thread after writing your mail?!? Is that
what happened? (I have to wonder why?)

Because it was at the bottom!

However, it doesn’t explain much.

To get special refinement of __FILE__ values, it sounds like you have
three choices: fix your own build system so cmake doesn’t directly invoke
the compiler, fix cmake, or fix all the compilers compatible with cmake.

I think you're missing something, and I'm guessing you have never used
cmake.

Only as a client. I’ve never tried to create a makefile. Probably never will, because it’s very unfriendly when it doesn’t work.

I suggest leaving cmake out of the discussion. I provided the link for
context and to indicate what motivated starting the thread here in the first
place. If it causes confusion, then ignore cmake.

Any other tool would provide the relative pathnames you want. Why don’t you ignore cmake and be done with the problem?

Note that the command-line option -D__FILE__='"original/path"' works on Clang and GCC, albeit with a warning. That might be the basis of a fairly portable workaround, with no need to modify any tools.

David Krauss

unread,
Jul 16, 2015, 12:49:45 AM7/16/15
to std-dis...@isocpp.org

On 2015–07–16, at 6:29 AM, Nevin Liber <ne...@eviloverlord.com> wrote:

That being said, given that string_view cannot by design necessarily be constructed in a constexpr context even though it has a constexpr constructor, it probably isn't all that useful for file_name to be constexpr.

What’s the problem with compile-time use of string_view? Being basically a pair of pointers, it should be as accessible as an initializer_list<char>, right?

Nevin Liber

unread,
Jul 16, 2015, 1:09:01 AM7/16/15
to std-dis...@isocpp.org
On 15 July 2015 at 23:49, David Krauss <pot...@mac.com> wrote:

On 2015–07–16, at 6:29 AM, Nevin Liber <ne...@eviloverlord.com> wrote:

That being said, given that string_view cannot by design necessarily be constructed in a constexpr context even though it has a constexpr constructor, it probably isn't all that useful for file_name to be constexpr.

What’s the problem with compile-time use of string_view?

You cannot construct it, because the char_traits functions it calls underneath are not constexpr.  I've been told the constexpr on the basic_string_view constructor<charT, traits> is designed for those people who use their own traits instead of std::char_traits and not for the users of string_view, wstring_view, u16string_view and u32string_view, in much the same way that pair has constexpr constructors.  For the record, I do not agree with this position.  Anyway, LWG 2232 goes into some detail on why this isn't easy to solve.  

David Krauss

unread,
Jul 16, 2015, 1:38:23 AM7/16/15
to std-dis...@isocpp.org
The constructor constexpr basic_string_view(const charT* str, size_type len) shouldn’t require traits. I’m surprised there isn’t also a template overload with a reference-to-array parameter. Perhaps because len isn’t supposed to include the NUL terminator?

I agree with you, though; char_traits has a lot more problems than benefits. The basic idea might have merit, but the current spec isn’t very useful.

Stephen Kelly

unread,
Jul 16, 2015, 2:19:37 AM7/16/15
to std-dis...@isocpp.org
David Krauss wrote:

>
>> On 2015–07–16, at 5:12 AM, Stephen Kelly <stev...@gmail.com> wrote:
>>
>> I'm trying to find out whether there is any point in putting any energy
>> into designing with these problems in mind, such as adding extra
>> information to the source_location.
>>
>> What do you think?
>
> The purpose of __FILE__ is to help with debugging. It’s widely used for
> that, with few complaints. source_location is supposed to be the same.

Ok.

> Let’s
> say, for the sake of argument, that the “build system” ends and the
> “compiler” begins when the file is opened.

Ok.

> The ambiguity in N4519 is that a source_location
> constructor invocation might refer to an unexpected source location.

Ok. I assume that if that's important someone will take care of it :).

> Any other tool would provide the relative pathnames you want. Why don’t
> you ignore cmake and be done with the problem?

Ok, I am now ignoring cmake. I don't see how that means I am 'done with the
problem' because I have been talking about direct invocation of the compiler
in this thread already since the beginning. I guess I'm missing something or
not understanding what you wrote.

> Note that the command-line option -D__FILE__='"original/path"' works on
> Clang and GCC, albeit with a warning. That might be the basis of a fairly
> portable workaround, with no need to modify any tools.

That was discussed in the thread, and it does not form a solution. It causes
the same __FILE__ to be used for #included files.

It seems the important conclusion is that:

1) __FILE__ is not intended to be useful outside of debugging use-cases.
2) source_location is not intended to have more use-cases than __FILE__.

Stephen Kelly

unread,
Jul 16, 2015, 2:25:14 AM7/16/15
to std-dis...@isocpp.org
Stephen Kelly wrote:

>> Any other tool would provide the relative pathnames you want. Why don’t
>> you ignore cmake and be done with the problem?
>
> Ok, I am now ignoring cmake. I don't see how that means I am 'done with
> the problem' because I have been talking about direct invocation of the
> compiler in this thread already since the beginning. I guess I'm missing
> something or not understanding what you wrote.

I just realized that your recommendation is not really 'Don't use cmake'.
Rather it is 'use tools that cd to a different directory and use relative
paths for everything'.

Do any tools do that?

That seems to be a quite specific requirement/recommendation. Changing the
base of relative paths essentially as a side-effect.

Thanks,

Steve.

Stephen Kelly

unread,
Jul 16, 2015, 2:32:15 AM7/16/15
to std-dis...@isocpp.org
David Krauss wrote:

> The solution you proposed to this list was essentially to have the
> compiler process paths before opening them.

I'm quite sure I did not propose any solution at all.

However, what I had in mind was wondering

1) Is 'richer' compile time string processing possible?
2) Could source_location gain a member for 'the base path for relative
paths'? GCC would set that to its PWD.

Given enough information and functionality, source_location would be useful
in ways that __FILE__ is not.

Currently __FILE__ can give relative paths which are relative to an unknown
location.

Thanks,

Steve.

David Krauss

unread,
Jul 16, 2015, 3:01:03 AM7/16/15
to std-dis...@isocpp.org
On 2015–07–16, at 2:25 PM, Stephen Kelly <stev...@gmail.com> wrote:

I just realized that your recommendation is not really 'Don't use cmake'.
Rather it is 'use tools that cd to a different directory and use relative
paths for everything’.

Do any tools do that?

According to the linked OP:
Over the last several decades, at least on the POSIX platform, it has
become common practice to invoke compilers with relative file paths, and
compilers have adopted to act accordingly. While the true culprit is the
C standard's lax definition of __FILE__, I'm blaming cmake's unusual,
absolute-path invocation behavior.
I’m not an expert on builds. I know that it’s common practice for GNU-style makefiles. 


On 2015–07–16, at 2:32 PM, Stephen Kelly <stev...@gmail.com> wrote:

However, what I had in mind was wondering 

1) Is 'richer' compile time string processing possible?

Yes, the general direction is to support parsing and some degree of interpretation using constexpr, TMP, and expression templates.

2) Could source_location gain a member for 'the base path for relative 
paths'? GCC would set that to its PWD.

Since that wouldn’t depend on the source location, it should be a global constant variable instead.

Also, the purpose of source_location is to avoid imposing macros where they’re unwanted, but many use cases are macro-based anyway. The constant might as well be a __CWD__ macro. You can already create that on the command line. Since you’d only want it to be available when using relative paths, arguably the idea shouldn’t be integrated into the implementation any closer than that.

Stephen Kelly

unread,
Jul 16, 2015, 3:59:15 AM7/16/15
to std-dis...@isocpp.org
David Krauss wrote:
>> Do any tools do that?
>
> I’m not an expert on builds. I know that it’s common practice for
> GNU-style makefiles.

By 'common practice' you mean 'you can write Makefiles by hand to do this
and the style guide might even recommend it', not 'here is a tool which does
that'. Correct?

I was asking about (possibly widely-used) tools which are designed to cd
into a particular directory and invoke the compiler there, not asking about
a style-guide. Maybe automake does this - I don't know.

>> 2) Could source_location gain a member for 'the base path for relative
>> paths'? GCC would set that to its PWD.
>
> Since that wouldn’t depend on the source location, it should be a global
> constant variable instead.

Perhaps. However, the source_location::file_name doesn't have any anchored
meaning without such a base if it is relative, so there is reason to add
such a thing to source_location. It gives meaning to something which
otherwise does not have meaning in certain contexts.

> Also, the purpose of source_location is to avoid imposing macros where
> they’re unwanted, but many use cases are macro-based anyway.

I wonder if source_location::file_name removes any need for macros at all.
If source_location had a member for the base path, there would not be a need
for a PWD macro.

> The constant
> might as well be a __CWD__ macro. You can already create that on the
> command line.

It is true that such a macro could be created easily on the command line.
All portable code using source_location::file_name would need it, because it
is impossible to know (in portable code) whether the
source_location::file_name will be absolute or relative, and relative to
what.

So, a library could require all clients to define the BOOST_CWD macro and
then in the header file the source_location::file_name and the macro need to
be used. So,

1) The goal of source_location replacing macros has not been satisfied.
2) The macro name is non-standard, so different code requires different
macros.

I don't propose standardizing such a macro - that would be a step in the
wrong direction. I am wondering whether it would make sense to extend
source_location with more stuff instead.

I don't know if 'more stuff' means adding some kind of PWD information or
not, or whether there is something else that would be useful instead. I am
trying to start an open discussion on that, but I don't think this
discussion feels very open. I'm aiming for something more like
brainstorming, but it feels like the response is just restriction to status
quo rather than imagination. Of course I do realize that your experience
leads you to have intuition for what is possible and what is not. This is
the important paragraph in this email.

Just look at any library designed for handling file paths and you will see
that knowledge about whether a file is relative or absolute and what it is
relative to is essential to making use of the content.

I know you have said source_location is only designed for debugging (that is
not clear from the papers I read about it, but you said it so let's take it
as true). The question I am raising is:


Can we imagine something better?


> Since you’d only want it to be available when using relative
> paths, arguably the idea shouldn’t be integrated into the implementation
> any closer than that.

I don't reach the same conclusion. I think source code should be as
independent from 'how the compiler was invoked' as possible. If
source_location stored the PWD, it could have an accessor for
absolute_file_name which is always absolute (using some compile time string
processing). Portable source code would rely on it being absolute
independent of how the compiler was invoked.

Bo Persson wrote that not all systems use paths at all. Presumably __FILE__
and source_location::file_name is entirely useless on such systems anyway
(along with the std::filesystem stuff).

Thanks,

Steve.

bennroot

unread,
Jul 16, 2015, 7:46:01 AM7/16/15
to std-dis...@isocpp.org, stev...@gmail.com, rwdo...@gmail.com, Abinaya V
AndroidWallpaper.jpg

Nevin Liber

unread,
Jul 16, 2015, 10:50:13 AM7/16/15
to std-dis...@isocpp.org
On 16 July 2015 at 00:38, David Krauss <pot...@gmail.com> wrote:
The constructor constexpr basic_string_view(const charT* str, size_type len) shouldn’t require traits.

Why on earth would it be obvious to call that one over

constexpr basic_string_view(const charT* str);

for a constexpr string literal?  Yeah, sure, *I* know why, but if one has to understand the implementation instead of just the interface to get their code to compile, it isn't much of an abstraction.
 
I’m surprised there isn’t also a template overload with a reference-to-array parameter. Perhaps because len isn’t supposed to include the NUL terminator?

Because it is trying to do what basic_string does, and treat embedded NULs in a C-string the same way.

David Krauss

unread,
Jul 16, 2015, 11:07:34 AM7/16/15
to std-dis...@isocpp.org
On 2015–07–16, at 10:49 PM, Nevin Liber <ne...@eviloverlord.com> wrote:

On 16 July 2015 at 00:38, David Krauss <pot...@gmail.com> wrote:
The constructor constexpr basic_string_view(const charT* str, size_type len) shouldn’t require traits.

Why on earth would it be obvious to call that one over

Not particularly obvious, but still more obvious than defining a char_traits<char>-alike with constexpr members :) . 

Robert Douglas

unread,
Jul 21, 2015, 9:44:32 AM7/21/15
to Stephen Kelly, std-dis...@isocpp.org

Hi Stephen,

Thank you for the interest.

The answers boil down to one idea: quality of implementation.
source_location is intentionally underspecified for several reasons:
1. Theres really no definition of a "file" in c++. The files and file systems are talked about informally, afaik.
2. I intentionally left each of these strings with the possibility of being empty and compliant. For those who wish to tool their binary by stripping all strings out to save space, or to remove code information for security concerns.
3. It was a non-starter in my opinion, to impose any requirements on the file system so that code would execute identically for things like sorting or identification, cross-platform. To avoid user expectation of that behavior, it was left unspecified what values the contents have.

A good implementation should replicate the values its corresponding preprocessor would generate.

The explicit intent of the class is to enable the development of functions to replace function-macros for things like logging, testing, and invariant checking, where output is generated for human consumption. As this is the first proposal to make it out of the committies reflection study group, underspecification leaves room to further define values, as we get larger feedback on how the feature may also be used. I believe the class is useful as it stands, and provides a great point to expand and refine in the future.

Im not sure if this answers your questions reasonably, but the summary is that there are no real guarantees as to what happens at runtime, other than it's a valid NTBS, and thus can be reliably printed, presumably with useful values, especially when you arent compiling static libraries on separate machines with abi-compatible-but-not-text-equivalent headers.

Just to belabor the point, you /should/ get the same values as you would for the corresponding __FILE__ et al, though that is currently officially QoI.

If I am not too presumptuous, could I infer a desire to have some sort of "absolute_path_file" with the same caveat, that it "should" do what the user excepts and give a non-relative-path file name?

-Rob

(Typed with a reckless disregard for spelling and grammar on my phone)

Myriachan

unread,
Jul 21, 2015, 1:52:01 PM7/21/15
to std-dis...@isocpp.org, rwdo...@gmail.com, stev...@gmail.com


On Tuesday, July 21, 2015 at 6:44:32 AM UTC-7, Robert Douglas wrote:

Hi Stephen,

Thank you for the interest.

The answers boil down to one idea: quality of implementation.
source_location is intentionally underspecified for several reasons:
1. Theres really no definition of a "file" in c++. The files and file systems are talked about informally, afaik.
2. I intentionally left each of these strings with the possibility of being empty and compliant. For those who wish to tool their binary by stripping all strings out to save space, or to remove code information for security concerns.
3. It was a non-starter in my opinion, to impose any requirements on the file system so that code would execute identically for things like sorting or identification, cross-platform. To avoid user expectation of that behavior, it was left unspecified what values the contents have.

A good implementation should replicate the values its corresponding preprocessor would generate.



What would be the effect of the #line preprocessor directive changing the filename?

Melissa

Robert Douglas

unread,
Jul 21, 2015, 3:55:08 PM7/21/15
to Myriachan, std-dis...@isocpp.org, Stephen Kelly

It behaves as __FILE__ ([cpp.predefined] p1) in coordination with [cpp.line] p4, as found in n4431. (open-std.org/JTC1/SC22/WG21/docs/papers/2015/n4431.pdf)

That is, #line taking a string can be observed to influence the contents of a further usage of source_location in the translation unit.

Stephen Kelly

unread,
Jul 21, 2015, 4:06:48 PM7/21/15
to Robert Douglas, std-dis...@isocpp.org
On 07/16/2015 03:11 PM, Robert Douglas wrote:
Hi Stephen,

Thank you for the interest.
Hi Robert,

Thanks for the response. 

The answers boil down to one idea: quality of implementation.
source_location is intentionally underspecified for several reasons:
1. Theres really no definition of a "file" in c++. The files and file
systems are talked about informally, afaik.
2. I intentionally left each of these strings with the possibility of
being empty and compliant. For those who wish to tool their binary by
stripping all strings out to save space, or to remove code information
for security concerns.
3. It was a non-starter in my opinion, to impose any requirements on
the file system so that code would execute identically for things like
sorting or identification, cross-platform. To avoid user expectation
of that behavior, it was left unspecified what values the contents have.

A good implementation should replicate the values its corresponding
preprocessor would generate.
Given the above, I am left wondering why it is useful at all. Is there
any example snippet of code which is useful, and preferably which only
relies on what is standardized, if there is any such use-case?

What can a programmer portably do with source_location? Let's assume
that the programmer is using recent GCC/Clang/MSVC on desktop systems,
and the strings are not stripped to save space, if that makes things easy.

Im not sure if this answers your questions reasonably, but the summary
is that there are no real guarantees as to what happens at runtime,
other than it's a valid NTBS, and thus can be reliably printed.

Is 'unprocessed' printing the only thing that a programmer can do with
source_location information? That seemed to be the opinion of David 
Krauss - that the only intended use-case is local debugging.

If I am not too presumptuous, could I infer a desire to have some sort
of "absolute_path_file" with the same caveat, that it "should" do what
the user excepts and give a non-relative-path file name?
I could at least imagine how that could be useful.

Is there anything else to say about why that is not included in the
proposal?

Thanks,

Steve.

Nevin Liber

unread,
Jul 21, 2015, 4:38:52 PM7/21/15
to std-dis...@isocpp.org
On 21 July 2015 at 15:06, Stephen Kelly <stev...@gmail.com> wrote:
Given the above, I am left wondering why it is useful at all.
Are you saying that __FILE__ isn't useful?
What can a programmer portably do with source_location?

Not portable != not useful.
 
 If I am not too presumptuous, could I infer a desire to have some sort
of "absolute_path_file" with the same caveat, that it "should" do what
the user excepts and give a non-relative-path file name?
I could at least imagine how that could be useful.

Well, sure.  As we like to say on the committee, we all want unicorns. :-)

But it is notoriously difficult to define "absolute path" in an OS-independent filesystem-independent way.  And it still isn't sufficient, as there may be multiple absolute paths to a given file, due to various hard links, sym links and mount points along the way.  

So, let's say Gandalf magically invents an absolute canonical path for every file in the universe.  That still isn't good enough, because the absolute canonical path on my build machine isn't the path name I need for portability.
Is there anything else to say about why that is not included in the
proposal?

There are an infinite number of things not included in the proposal. :-)

If you have a solution to "absolute path" that is OS-independent, filesystem-independent, doesn't boil down to QoI and can be use in a portable way, then by all means make a proposal.

Stephen Kelly

unread,
Jul 23, 2015, 3:11:23 AM7/23/15
to std-dis...@isocpp.org
Nevin Liber wrote:

> On 21 July 2015 at 15:06, Stephen Kelly <stev...@gmail.com> wrote:
>
>> Given the above, I am left wondering why it is useful at all.
>>
>> Are you saying that __FILE__ isn't useful?
>
>> What can a programmer portably do with source_location?
>
> Not portable != not useful.

I don't challenge that.

In fact, as you said, an API for absolute paths would be useful but not
portable. So we seems to agree on that :).

If the source_location already has no intentions of portability, then
what's the problem with adding an absolute_path accessor? It can have
'undefined content' if that helps, just like the file_name.

>> If I am not too presumptuous, could I infer a desire to have some sort
>>
>> of "absolute_path_file" with the same caveat, that it "should" do what
>> the user excepts and give a non-relative-path file name?
>>
>> I could at least imagine how that could be useful.
>
> Well, sure. As we like to say on the committee, we all want unicorns. :-)

My point was that I have trouble imagining the usefulness of the current
proposal. That's why I asked what makes it useful.

I can imagine absolute paths being useful. I can't imagine the current
proposal of file_name being useful for anything other than printing a path
on a build machine. We agree that is undesirable.

That's not really what I'm looking for though. I'm looking for paths to be
relative to some path which is well-defined (and perhaps specified by the
user). That would make the content of file_name useful.

Additionally, it has been suggested that source_location exists to replace a
macro (__FILE__). It has further been suggested that
source_location::file_name would need to be processed together with content
specified by the user in a macro. The logic is circular.

> But it is notoriously difficult to define "absolute path" in an
> OS-independent filesystem-independent way.

Right. It's as portable as source_location::file_name.

What is the filesystem TS response to the absolute path theme?

Note that absolute paths are not what I'm looking for and I never suggested
I was looking for them. I only said I could imagine them being useful in
ways that the current 'relative to unknown' content is not useful.

Other people have simply guessed that and assumed that the only answer is
absolute paths. I really don't believe that is the only answer, which is why
I keep asking for more imagination :).

> So, let's say Gandalf magically invents an absolute *canonical* path for
> every file in the universe. That still isn't good enough, because the
> absolute canonical path on my build machine isn't the path name I need for
> portability.

Who cares about portability! :) You said yourself that we're not talking
about portability if we're talking about source_location.

I think you are saying that it is not appropriate to hardcode absolute
paths from your build machine into binaries you ship elsewhere. I agree. I
don't think absolute paths should be compiled into anything. I also don't
think relative paths with unknown bases should be compiled into anything.

I did say that if source_location provided absolute paths, and if there was
a way to process that content at compile time, then the absolute paths could
be converted to paths relative to a *deterministic* base, at least in the
absence of wild symlinking. I just 'suspended disbelief' for a moment to get
past that so that I could use imagination.

I guess an implementation could add a way to allow the user to specify what
the file_name should be relative to for example. If one implementation
provides such a thing then it can't be relied upon. So, I'm asking for you
to imagine how to specify source_location so that it is useful for all
implementations.

I realize that 'make paths relative to a deterministic base' might not be
what you think of as 'useful'. That is why I keep asking:

1) What makes source_location useful as it is specified today
2) What other use-cases could be satisfied with source_location, if some
imagination is engaged.

Thanks,

Steve.
Reply all
Reply to author
Forward
0 new messages