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.
On 2015–07–12, at 6:23 PM, Stephen Kelly <stev...@gmail.com> wrote:What is a 'presumed name'? I realize it issomething 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?
1) The __FILE__ macro expands to a relative orabsolute 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.
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?
My original mail can not be understood if you do not read the thread I
linked.
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.
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.
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.
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?
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?
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.
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?
2) Could source_location gain a member for 'the base path for relative
paths'? GCC would set that to its PWD.
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?
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
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)
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.
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.
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.
Given the above, I am left wondering why it is useful at all.
What can a programmer portably do with source_location?
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?