Why is __func__ lowercase while __FILE__ and __LINE__ are uppercase? [duplicate] - c++

I've just noticed that __func__, __FUNCTION__ and __PRETTY_FUNCTION__ aren't treated as preprocessor macros and they're not mentioned on the 16.8 Predefined macro names section of the Standard (N4527 Working Draft).
This means that they cannot be used in the string concatenation trick of phase 6:
// Valid
constexpr char timestamp[]{__FILE__ " has been compiled: " __DATE__ " " __TIME__};
// Not valid!!!
template <typename T>
void die() { throw std::runtime_error{"Error detected in " __PRETTY_FUNCTION__}; }
As far as I know, the __FILE__, __DATE__ and __TIME__ are translated to string literals as stated by the standard:
16.8 Predefined macro names [cpp.predefined]
__DATE__
The date of translation of the source file: a character string literal of the form "Mmm dd yyyy", where the names of the months are the same as those generated by the asctime function, and the first character of dd is a space character if the value is less than 10. If the date of translation is not
available, an implementation-defined valid date shall be supplied.
__FILE__
The presumed name of the current source file (a character string literal).
__TIME__
The time of translation of the source file: a character string literal of the form "hh:mm:ss" as in the time generated by the asctime function.
__func__ is mentioned by the standard as a function-local predefined variable of the form:
static const char __func__[] = "function-name ";
So the fact is that is a local variable hence the string concatenation trick doesn't works with it.
As for __FUNCTION__ and __PRETTY_FUNCTION__ aren't mentioned in the standard (are implementation defined?) but is a pretty safe bet to think that they would behave like __func__.
So the question is: Why __func__, __FUNCTION__ and __PRETTY_FUNCTION__ are function-local static constant array of characters while __FILE__, __DATE__ and __TIME__ are string literals? What's the rationale (if any) behind this decision?

Expanding __func__ at preprocessing time requires the preprocessor to know which function it's processing. The preprocessor generally doesn't know that, because parsing happens after the preprocessor is already done.
Some implementations combine the preprocessing and the parsing, and in those implementations, it would have been possible for __func__ to work the way you'd like it to. In fact, if I recall correctly, MSVC's __FUNCTION__ works like that. It's an unreasonable demand on implementations that separate the phases of translation though.

Related

Is it safe to use `basename` with __FILE__?

The title is pretty clear: Is it safe to use basename (man 3 basename) with __FILE__ ?.
It compiles and seems to work fine, but basename's argument is char* (not const char*) and the man-page says:
Both dirname() and basename() may modify the contents of path, so it may be desirable to pass a copy when calling one of these functions.
So, this makes me worry.
Maybe the question should be more like: what is the type of __FILE__? Isn't it a string literal / const char*? But if it is, why there's no a compile-time error (const char* to char*)?
Read carefully basename(3) and notice:
Warning: there are two different functions basename() - see below.
and take care of the NOTES saying
There are two different versions of basename() - the POSIX version
described above, and the GNU version, which one gets after
#define _GNU_SOURCE /* See feature_test_macros(7) */
#include <string.h>
The GNU version never modifies its argument, and returns the empty
string when path has a trailing slash
(emphasis is mine)
Because it is said that the GNU version does not modify its argument, using it is safe with __FILE__
BTW, you could consider customizing your GCC (e.g. with MELT) to define some __builtin_basename which would compute the basename at compile time if given a string literal like __FILE__ or else invoke basename at runtime.
Notice that libgen.h has #define basename __xpg_basename
what is the type of __FILE__? Isn't it a string literal / const char*?
Yes. It's a string literal.
But if it is, why there's no a compile-time error (const char* to char*)?
Possibly because the implementation you use (glibc's) may be returning a pointer within the string literal you pass (i.e. it doesn't modify its input).
In any case, you can't rely on it for the above stated below.
C standard (c11, § 6.10.8.1) says the __FILE__ is a string literal:
__FILE__ The presumed name of the current source file (a character string siteral).
POSIX says:
The basename() function may modify the string pointed to by path,
and may return a pointer to internal storage. The returned pointer
might be invalidated or the storage might be overwritten by a
subsequent call to basename().
(emphasis mine).
So, no, it's not safe to call basename() with __FILE__. You can simply take a copy of __FILE__ and do basename() on it:
char *filename = strdup(__FILE__);
if (filename) {
/* error */
}
char *file_basename = basename(filename);
free(filename);
Since __FILE__ is a string literal, using an array is another option:
char filename[] = __FILE__;
char *file_basename = basename(filename);

Why would __FUNCTION__ be undefined?

I have a C++ library that uses the predefined macro __FUNCTION__, by way of crtdefs.h. The macro is documented here. Here is my usage:
my.cpp
#include <crtdefs.h>
...
void f()
{
L(__FUNCTIONW__ L" : A diagnostic message");
}
static void L(const wchar_t* format, ...)
{
const size_t BUFFERLENGTH = 1024;
wchar_t buf[BUFFERLENGTH] = { 0 };
va_list args;
va_start(args, format);
int count = _vsnwprintf_s(buf, BUFFERLENGTH, _TRUNCATE, format, args);
va_end(args);
if (count != 0)
{
OutputDebugString(buf);
}
}
crtdefs.h
#define __FUNCTIONW__ _STR2WSTR(__FUNCTION__)
The library (which is compiled as a static library, if that matters) is consumed by another project in the same solution, a WPF app written in C#.
When I compile the lib, I get this error:
identifier "L__FUNCTION__" is undefined.
According to the docs, the macro isn't expanded if /P or /EP are passed to the compiler. I have verified that they are not. Are there other conditions where this macro is unavailable?
You list the error as this:
identifier "L__FUNCTION__" is undefined.
Note it's saying "L__FUNCTION__" is not defined, not "__FUNCTION__".
Don't use __FUNCTIONW__ in your code. MS didn't document that in the page you linked, they documented __FUNCTION__. And you don't need to widen __FUNCTION__.
ETA: I also note that you're not assigning that string to anything or printing it in anyway in f().
Just use
L(__FUNCTION__ L" : A diagnostic message");
When adjacent string literals get combined, the result will be a wide string if any of the components were.
There's nothing immediately wrong with using L as the name of a function... it's rather meaningless however. Good variable and function identifiers should be descriptive in order to help the reader understand the code. But the compiler doesn't care.
Since your L function wraps vsprintf, you may also use:
L(L"%hs : A diagnostic message", __func__);
since __func__ is standardized as a narrow string, the %hs format specifier is appropriate.
The rule is found in 2.14.5p13:
In translation phase 6 (2.2), adjacent string literals are concatenated. If both string literals have the same encoding-prefix, the resulting concatenated string literal has that encoding-prefix. If one string literal has no encoding-prefix, it is treated as a string literal of the same encoding-prefix as the other operand. If a UTF-8 string literal token is adjacent to a wide string literal token, the program is ill-formed. Any other concatenations are conditionally-supported with implementation-defined behavior.
I think the definition of __FUNCTIONW__ is incorrect. (I know you did not write it.)
From: http://gcc.gnu.org/onlinedocs/gcc/Function-Names.html
These identifiers are not preprocessor macros. In GCC 3.3 and earlier,
in C only, __FUNCTION__ and __PRETTY_FUNCTION__ were treated as string
literals; they could be used to initialize char arrays, and they could
be concatenated with other string literals. GCC 3.4 and later treat
them as variables, like __func__. In C++, __FUNCTION__ and
__PRETTY_FUNCTION__ have always been variables.
At least in current GCC then you cannot prepend L to __FUNCTION__, because it is like trying to prepend L to a variable. There probably was a version of VC++ (like there was of GCC) where this would have worked, but you are not using that version.

How can the C++ Preprocessor be used on strings?

The preprocessor can be used to replace certain keywords with other words using #define. For example I could do #define name "George" and every time the preprocessor finds 'name' in the program it will replace it with "George".
However, this only seems to work with code. How could I do this with strings and text? For example if I print "Hello I am name" to the screen, I want 'name' to be replaced with "George" even though it is in a string and not code.
I do not want to manually search the string for keywords and then replace them, but instead want to use the preprocessor to just switch the words.
Is this possible? If so how?
I am using C++ but C solutions are also acceptable.
#define name "George"
printf("Hello I am " name "\n");
Adjacent string literals are concatenated in C and C++.
Quotes from C and C++ Standard:
For C (quoting C99, but C11 has something similar in 6.4.5p5):
(C99, 6.4.5p5) "In translation phase 6, the multibyte character sequences specified by any sequence of adjacent character and identically-prefixed string literal tokens are concatenated into a single multibyte character sequence."
For C++:
(C++11, 2.14.5p13) "In translation phase 6 (2.2), adjacent string literals are concatenated."
EDIT: as requested, add quotes from C and C++ Standard. Thanks to #MatteoItalia for the C++11 quote.
#define name "George"
printf("Hello I am %s\n", name);
Here name will be replaced by "George"
Your issue is that the preprocessor will (wisely) not replace tokens that are inside string literals.
So you must either use a function like printf or a variable rather than the preprocessor, or pull the token out of the string like so:
#include <iostream>
#define name "George"
int main(int argc, char** argv) {
std::cout << "Hello I am " << name << std::endl;
}

String concatenation using preprocessor

is it possible to concatenate strings during preprocessing?
I found this example
#define H "Hello "
#define W "World!"
#define HW H W
printf(HW); // Prints "Hello World!"
However it does not work for me - prints out "Hello" when I use gcc -std=c99
UPD This example looks like working now. However, is it a normal feature of c preprocessor?
Concatenation of adjacent string litterals isn't a feature of the preprocessor, it is a feature of the core languages (both C and C++). You could write:
printf("Hello "
" world\n");
You can indeed concatenate tokens in the preprocessor, but be careful because it's tricky. The key is the ## operator. If you were to throw this at the top of your code:
#define myexample(x,y,z) int example_##x##_##y##_##z## = x##y##z
then basically, what this does, is that during preprocessing, it will take any call to that macro, such as the following:
myexample(1,2,3);
and it will literally turn into
int example_1_2_3 = 123;
This allows you a ton of flexibility while coding if you use it correctly, but it doesn't exactly apply how you are trying to use it. With a little massaging, you could get it to work though.
One possible solution for your example might be:
#define H "Hello "
#define W "World!"
#define concat_and_print(a, b) cout << a << b << endl
and then do something like
concat_and_print(H,W);
From gcc online docs:
The '##' preprocessing operator performs token pasting. When a macro is expanded, the two tokens on either side of each '##' operator are combined into a single token, which then replaces the '##' and the two original tokens in the macro expansion.
Consider a C program that interprets named commands. There probably needs to be a table of commands, perhaps an array of structures declared as follows:
struct command
{
char *name;
void (*function) (void);
};
struct command commands[] =
{
{ "quit", quit_command },
{ "help", help_command },
...
};
It would be cleaner not to have to give each command name twice, once in the string constant and once in the function name. A macro which takes the name of a command as an argument can make this unnecessary. The string constant can be created with stringification, and the function name by concatenating the argument with _command. Here is how it is done:
#define COMMAND(NAME) { #NAME, NAME ## _command }
struct command commands[] =
{
COMMAND (quit),
COMMAND (help),
...
};
I just thought I would add an answer that cites the source as to why this works.
The C99 standard §5.1.1.2 defines translation phases for C code. Subsection 6 states:
Adjacent string literal tokens are concatenated.
Similarly, in the C++ standards (ISO 14882) §2.1 defines the Phases of translation. Here Subsection 6 states:
6 Adjacent ordinary string literal tokens are concatenated. Adjacent wide string literal tokens are concatenated.
This is why you can concatenate strings simply by placing them adjacent to one another:
printf("string"" one\n");
>> ./a.out
>> string one
The preprocessing part of the question is simply the usage of the #define preprocessing directive which does the substitution from identifier (H) to string ("Hello ").

C/C++ line number

In the sake of debugging purposes, can I get the line number in C/C++ compilers?
(standard way or specific ways for certain compilers)
e.g
if(!Logical)
printf("Not logical value at line number %d \n",LineNumber);
// How to get LineNumber without writing it by my hand?(dynamic compilation)
You should use the preprocessor macro __LINE__ and __FILE__. They are predefined macros and part of the C/C++ standard. During preprocessing, they are replaced respectively by a constant string holding an integer representing the current line number and by the current file name.
Others preprocessor variables :
__func__ : function name (this is part of C99, not all C++ compilers support it)
__DATE__ : a string of form "Mmm dd yyyy"
__TIME__ : a string of form "hh:mm:ss"
Your code will be :
if(!Logical)
printf("Not logical value at line number %d in file %s\n", __LINE__, __FILE__);
As part of the C++ standard there exists some pre-defined macros that you can use. Section 16.8 of the C++ standard defines amongst other things, the __LINE__ macro.
__LINE__: The line number of the current source line (a decimal
constant).
__FILE__: The presumed name of the source file (a character string
literal).
__DATE__: The date of translation of the source file (a character string
literal...)
__TIME__: The time of translation of the source file (a character string
literal...)
__STDC__: Whether__STDC__ is predefined
__cplusplus: The name __cplusplus is defined to the value 199711L when
compiling a C ++ translation unit
So your code would be:
if(!Logical)
printf("Not logical value at line number %d \n",__LINE__);
You could use a macro with the same behavior as printf(),
except that it also includes debug information such as
function name, class, and line number:
#include <cstdio> //needed for printf
#define print(a, args...) printf("%s(%s:%d) " a, __func__,__FILE__, __LINE__, ##args)
#define println(a, args...) print(a "\n", ##args)
These macros should behave identically to printf(), while including java stacktrace-like information. Here's an example main:
void exampleMethod() {
println("printf() syntax: string = %s, int = %d", "foobar", 42);
}
int main(int argc, char** argv) {
print("Before exampleMethod()...\n");
exampleMethod();
println("Success!");
}
Which results in the following output:
main(main.cpp:11) Before exampleMethod()...
exampleMethod(main.cpp:7) printf() syntax: string = foobar, int = 42
main(main.cpp:13) Success!
C++20 offers a new way to achieve this by using std::source_location. This is currently accessible in gcc an clang as std::experimental::source_location with #include <experimental/source_location>.
The problem with macros like __LINE__ is that if you want to create for example a logging function that outputs the current line number along with a message, you always have to pass __LINE__ as a function argument, because it is expanded at the call site.
Something like this:
void log(const std::string msg) {
std::cout << __LINE__ << " " << msg << std::endl;
}
Will always output the line of the function declaration and not the line where log was actually called from.
On the other hand, with std::source_location you can write something like this:
#include <experimental/source_location>
using std::experimental::source_location;
void log(const std::string msg, const source_location loc = source_location::current())
{
std::cout << loc.line() << " " << msg << std::endl;
}
Here, loc is initialized with the line number pointing to the location where log was called.
You can try it online here.
Use __LINE__ (that's double-underscore LINE double-underscore), the preprocessor will replace it with the line number on which it is encountered.
Checkout __FILE__ and __LINE__ macros
Try __FILE__ and __LINE__.
You might also find __DATE__ and __TIME__ useful.
Though unless you have to debug a program on the clientside and thus need to log these informations you should use normal debugging.
For those who might need it, a "FILE_LINE" macro to easily print file and line:
#define STRINGIZING(x) #x
#define STR(x) STRINGIZING(x)
#define FILE_LINE __FILE__ ":" STR(__LINE__)
Since i'm also facing this problem now and i cannot add an answer to a different but also valid question asked here,
i'll provide an example solution for the problem of:
getting only the line number of where the function has been called in C++ using templates.
Background: in C++ one can use non-type integer values as a template argument. This is different than the typical usage of data types as template arguments.
So the idea is to use such integer values for a function call.
#include <iostream>
class Test{
public:
template<unsigned int L>
int test(){
std::cout << "the function has been called at line number: " << L << std::endl;
return 0;
}
int test(){ return this->test<0>(); }
};
int main(int argc, char **argv){
Test t;
t.test();
t.test<__LINE__>();
return 0;
}
Output:
the function has been called at line number: 0
the function has been called at line number: 16
One thing to mention here is that in C++11 Standard it's possible to give default template values for functions using template. In pre C++11 default values for non-type arguments seem to only work for class template arguments. Thus, in C++11, there would be no need to have duplicate function definitions as above. In C++11 its also valid to have const char* template arguments but its not possible to use them with literals like __FILE__ or __func__ as mentioned here.
So in the end if you're using C++ or C++11 this might be a very interesting alternative than using macro's to get the calling line.
Use __LINE__, but what is its type?
LINE The presumed line number (within the current source file) of the current source line (an integer constant).
As an integer constant, code can often assume the value is __LINE__ <= INT_MAX and so the type is int.
To print in C, printf() needs the matching specifier: "%d". This is a far lesser concern in C++ with cout.
Pedantic concern: If the line number exceeds INT_MAX1 (somewhat conceivable with 16-bit int), hopefully the compiler will produce a warning. Example:
format '%d' expects argument of type 'int', but argument 2 has type 'long int' [-Wformat=]
Alternatively, code could force wider types to forestall such warnings.
printf("Not logical value at line number %ld\n", (long) __LINE__);
//or
#include <stdint.h>
printf("Not logical value at line number %jd\n", INTMAX_C(__LINE__));
Avoid printf()
To avoid all integer limitations: stringify. Code could directly print without a printf() call: a nice thing to avoid in error handling2 .
#define xstr(a) str(a)
#define str(a) #a
fprintf(stderr, "Not logical value at line number %s\n", xstr(__LINE__));
fputs("Not logical value at line number " xstr(__LINE__) "\n", stderr);
1 Certainly poor programming practice to have such a large file, yet perhaps machine generated code may go high.
2 In debugging, sometimes code simply is not working as hoped. Calling complex functions like *printf() can itself incur issues vs. a simple fputs().