#include <iostream>
#include <cstdlib>
int main() {
cout << "!!!Hello World!!!" << endl;
system("pause");
return main();
}
The above works, but it hardcoded the main() function. Is there a magic variable or macro to get the current running function?
Is it allowed in "C++"? No.
In practice, can you call main()? Yes.
Whatever the C++ Standard says, that doesn't stop the Linux g++ compiler from compiling code with main() in main().
#include <cstdlib>
#include <iostream>
using namespace std;
int main()
{
int y = rand() % 10; // returns 3, then 6, then 7
cout << "y = " << y << endl;
return (y == 7) ? 0 : main();
}
Which lets us do:
> g++ g.cpp; ./a.out
y = 3
y = 6
y = 7
Looking in to the assembly, we see that main is called just like any other function would be:
main:
...
cmpl $7, -12(%rbp)
je .L7
call main
...
.L7:
...
leave
ret
Not that this behavior is guaranteed, but it looks like g++ doesn't seem to really care about the standard, apart from this sarcastic warning with -pedantic
g.cpp:8: error: ISO C++ forbids taking address of function '::main'
The C++ Standard says that you may not call main() from your own code. As for getting the name of the current function, you could use the __FUNCTION__ macro, but once again this is not standard:
#include <iostream>
using namespace std;
void foo() {
cout << __FUNCTION__ << endl;
}
int main() {
foo();
}
should print "foo" or something similar if __FUNCTION__ is supported.
If a specific implementation allows this, it is not behaving correctly(a). The standard state quite explicitly in C++14, 3.6.1 Main function /3:
The function main shall not be used within a program.
(a) Keep in mind that many implementations follow some parts of the standard loosely, preferring power over strictness. That can have the unfortunate side effect that your code may not be portable to other compilers or even other versions of the same compiler.
Many implementations will also allow you to take the stricter view, such as using g++ -std=c++11 -Werror=pedantic which catches the particular issue bought up in this question, as well as quite a few others. It is that "mode" of translation that allows implementations to claim to be compliant with the standard, as per 1.4 Implementation compliance:
If a program contains a violation of any diagnosable rule ..., a conforming implementation shall issue at least one diagnostic message.
You'll see it's still quite possible to allow the code to compile and run in that case, since "diagnostic message" can mean a warning rather than an error.
Generally, no. For now it will be enough for you to know that the compiler needs to know the exact function you're calling at the compile time. You cannot do magic like, let's say
func = "my_function";
func();
if the called function name will change during runtime. (There are exceptions and ways around that, but you don't need that).
Don't think about that as a case of hard-coding: it is not. If you need to call the function, then you just write its name, and don't try to abstract it, or something.
Also, now would be a nice way to learn about the while loop, infinite loops and write without the function calls at all, e.g
int main()
{
while (1) {
cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!!
system("pause");
}
}
Related
It explicitly says in the c++ standard documentation that a program may not call main. Yet I wrote a program that calls main and works perfectly fine, why is that? The code:
#include<iostream>
static int counter = 0;
int main(){
counter++;
std::cout << counter << " It works" << std::endl;
while(counter < 10){
main();
}
return 1;
}
It prints to console "It works" 10 times. According to the standard documentation, this should not work, yet it works. What's going on?
basic.start.main/3:
The function main shall not be used within a program.
Violating this rule makes your program have undefined behavior - which means that the program can do pretty much anything. It may even do what you wanted it to do or appear to do what you wanted but have devastating side effects, so avoid having undefined behavior in your programs.
Regarding the lack of diagnostic messages: I suspect that some compilers, like g++, actually support calling main as an extension. I had to turn on -pedantic or -pedantic-errors to get the diagnostic message "ISO C++ forbids taking address of function '::main' [-Wpedantic]"
Let's look at such piece of code:
#include <iostream>
int foo(int i) {return i; }
int foobar(int z) {return foo(z);}
int main() {
std::cout << foobar(3) << std::endl;
}
It compiles fine with g++ -std=c++11 ... and gives output 3. But The same output is given by:
#include <iostream>
int foo(int i) {return i; }
int foobar(int z) { foo(z);}
int main() {
std::cout << foobar(3) << std::endl;
}
It compiles without problems but clearly the keyword return is missed in foobar. Is it a bug in gcc 4.8.3 or maybe I'm not aware of some c++11 principle? (Runned on Fedora 20)
The C++ standard doesn't make a mandate for compilers to insist on a return-statement in functions return non-void. Instead, flowing off the end of such a function without a return-statement is undefined behavior. The relevant statement in the standard is in 6.6.3 [stmt.return] paragraph 2, last sentence (and in 3.6.1 [basic.start.main] paragraph 5 is the statement making it OK for main() to flow off this function):
Flowing off the end of a function is equivalent to a return with no value; this results in undefined behavior in a value-returning function.
The primary reason for this approach is that it may be non-trivial or even impossible if the function actually ever really returns. Consider this function declaration and function definition:
extern void will_always_throw();
int does_not_return_anything() {
will_always_throw();
}
Assuming will_always_throw() indeed does as the name suggests, there is nothing wrong. In fact, if the compiler gets smarter and manages to verify that will_always_throw(), indeed, always throws (or a "noreturn" attribute is attached to will_always_throw(), it may warn about the last statement in this definition never being reached:
int does_return_something_just_in_case() {
will_always_throw();
return 17;
}
The general approach to deal with these situations is for compilers to support suitable options enabling/disabling warnings as necessary. For example, on your code all compilers I have access to (gcc, clang, and icc) create a warning assuming warnings are enable (using -Wall for the first two and -w2 for Intel's compiler).
The code compiles fine because it is well-formed, and so you can run it. But since this is undefined behavior, you cannot rely on any behavior of the program, anything is legal. To prevent accidents like this, enable compiler warnings. if you compile your code with -Wall, you will see
main.cpp:10:28: warning: no return statement in function returning non-void [-Wreturn-type]
int foobar(int z) { foo(z);}
Here you can get more information about those warnings. Use them and make sure your code compiles warning free. It can catch a lot of errors in your code at compile time.
I follow this example http://www.tutorialspoint.com/cplusplus/cpp_inline_functions.htm:
#include <iostream>
using namespace std;
inline int Max(int x, int y)
{
return (x > y)? x : y;
}
// Main function for the program
int main( )
{
cout << "Max (20,10): " << Max(20,10) << endl;
cout << "Max (0,200): " << Max(0,200) << endl;
cout << "Max (100,1010): " << Max(100,1010) << endl;
return 0;
}
and tried removing the inline and still gives same results... so what does inline actually affect this?
inline has nothing whatsoever to do with the behavior of the function. The only thing it is required to do is alter the behavior of the linker, specifically to cause the linker to allow the same symbol to be defined in multiple translation units. inline never affects a program's observed behavior1, only whether or not it might link successfully.
In the past it was also used as a hint to the compiler that the function should be inlined whenever used, but this is not required by the C++ specification and modern compilers are very good at deciding whether to inline without input from the programmer.
In the code you have posted, inline will not have any observable effect.
1Unless you define a function multiple times differently in different translation units and declare them all inline -- but I think this invokes undefined behavior.
You can view the difference between your code's operation using assembly output.
To view this using g++ as a compiler, type:
g++ -S mySource.cpp -o assemblyWithInline
then remove your inline and try, for example,
g++ -S myNewSource.cpp -o assemblyWithoutInline
diff assemblyWithInline assemblyWithoutInline
This will display the difference between your two sets of code (as understood by your compiler, g++)
This may be the same, if your compiler optimises your code to automatically inline it.
The output in all cases will be the same, since your logic is not altered by the presence of an inline hint.
Inline is Just a hint for the compiler. It can provide somÄ™ measurable speed up of code making calls to Inline functions.
Modern compilers seam to be far more clever these days so they know in 99% situations where Inline would help and where code would suffer from such inline.
Basicly inlined function code is pasted at every (suitable) call instruction, reducing overhead of pushing and popping its arguments.
A few days back, I came across this piece of C++ code, though I can't paste the code itself, I could recreate the problem with some sample code.
First, the file, namespace.h:
#include <iostream>
using namespace std;
namespace useless{
class X {
int m_myint;
static X *m_foobar;
X* getPrivVal(void);
public:
int getMember(void);
X* getStaticVal(void);
};
}
Next, namespace.cpp:
#include "namespace.h"
extern "C"{
namespace useless{
X* X::m_foobar = NULL;
X* X::getPrivVal(void){
if(m_foobar == NULL)
m_foobar = new X;
return(m_foobar);
}
}
}
namespace useless {
int X::getMember(void){
if(m_myint == 0)
m_myint = 1;
return(m_myint);
}
X* X::getStaticVal(void){
return(getPrivVal());
}
}
using namespace useless;
int main(void){
X y;
cout << "The int value is " << y.getMember() << endl;
cout << "The value of the static member is " << y.getStaticVal() << endl;
return(0);
}
This code compiled and linked fine when I used g++ 3.4.3, but gives the following error when I use g++ 4.x, I have tried with GCC 4.6.1 as well GCC 4.2.1. Have tried it on Linux as well as Mac, same results.
This is the error(Suse):
g++ -o namespace namespace.cpp
namespace.h:8:15: error: previous declaration of useless::X*
useless::X::m_foobar with C++ linkage
namespace.cpp:5:11: error: conflicts with new declaration with C linkage
Can someone please shed some light on what the legacy C++ code was looking to do, could this have been a hack or workaround to get around an old problem that I am not aware of any longer. Ohh by the way, the method inside the extern "C" is called by C++ code and not any C code as I initially suspected.
FYI, this is legacy code now, may have been written in 2001/2002 period.
Thanks guys. I have gone ahead and got rid of the extern "C" with no major impact.
#Bjorn Pollex : The guy who wrote that code is long gone.
The extern "C" directive has two effects, it disables mangling when possible and uses the C calling convention. In this particular case, because there is a namespace in between, name mangling cannot be disabled, so it could have been added to force a particular calling convention.
The code is actually wrong in that the declaration does not force extern "C" but the definition does, which is incorrect. Consider that if the compiler just followed the directive as shown, the caller would use C++ naming and calling conventions, while the function would be using the C variant, if the two differ the result will be undefined behavior.
Seems like an attempt to generate the variables witout C++ name mangling. That's one part of using extern "C".
The newer compiler obviously realizes that it really doesn't work.
If you have a piece of C++ code that you want to call from a module written in another language (C, FORTRAN or whatever), you want to turn off C++ name mangling.
Edit:
The really weird thing is that they did it on the definition but not on the declaration. It's a wonder that it ever compiled
I want to implement a function tracer, which would trace how much time a function is taking to execute. I have following class for the same:-
class FuncTracer
{
public:
FuncTracer(LPCTSTR strFuncName_in)
{
m_strFuncName[0] = _T('\0');
if( strFuncName_in ||
_T('\0') != strFuncName_in[0])
{
_tcscpy(m_strFuncName,strFuncName_in);
TCHAR strLog[MAX_PATH];
_stprintf(strLog,_T("Entering Func:- <%s>"),m_strFuncName);
LOG(strLog)
m_dwEnterTime = GetTickCount();
}
}
~FuncTracer()
{
TCHAR strLog[MAX_PATH];
_stprintf(strLog,_T("Leaving Func:- <%s>, Time inside the func <%d> ms"),m_strFuncName, GetTickCount()-m_dwEnterTime);
LOG(strLog)
}
private:
TCHAR m_strFuncName[MAX_PATH];
DWORD m_dwEnterTime;
};
void TestClass::TestFunction()
{
// I want to avoid writing the function name maually..
// Is there any macro (__LINE__)or some other way to
// get the function name inside a function ??
FuncTracer(_T("TestClass::TestFunction"));
/*
* Rest of the function code.
*/
}
I want to know if there is any way to get the name of the function from inside of a function? Basically I want the users of my class to simply create an object the same. They may not pass the function name.
C99 has __func__, but for C++ this will be compiler specific. On the plus side, some of the compiler-specific versions provide additional type information, which is particularly nice when you're tracing inside a templatized function/class.
MSVC: __FUNCTION__, __FUNCDNAME__, __FUNCSIG__
GCC: __func__, __FUNCTION__, __PRETTY_FUNCTION__
Boost library has defined macro BOOST_CURRENT_FUNCTION for most C++ compilers in header boost/current_function.hpp. If the compiler is too old to support this, the result will be "(unknown)".
VC++ has
__FUNCTION__ for undecorated names
and
__FUNCDNAME__ for decorated names
And you can write a macro that will itself allocate an object and pass the name-yelding macro inside the constructor. Smth like
#define ALLOC_LOGGER FuncTracer ____tracer( __FUNCTION__ );
C++20 std::source_location::function_name
main.cpp
#include <iostream>
#include <string_view>
#include <source_location>
void log(std::string_view message,
const std::source_location& location = std::source_location::current()
) {
std::cout << "info:"
<< location.file_name() << ":"
<< location.line() << ":"
<< location.function_name() << " "
<< message << '\n';
}
int f(int i) {
log("Hello world!"); // Line 16
return i + 1;
}
int f(double i) {
log("Hello world!"); // Line 21
return i + 1.0;
}
int main() {
f(1);
f(1.0);
}
Compile and run:
g++ -ggdb3 -O0 -std=c++20 -Wall -Wextra -pedantic -o source_location.out source_location.cpp
./source_location.out
Output:
info:source_location.cpp:16:int f(int) Hello world!
info:source_location.cpp:21:int f(double) Hello world!
so note how the call preserves caller information, so we see the desired main call location instead of log.
I have covered the relevant standards in a bit more detail at: What's the difference between __PRETTY_FUNCTION__, __FUNCTION__, __func__?
Tested on Ubuntu 22.04, GCC 11.3.
I was going to say I didn't know of any such thing but then I saw the other answers...
It might interest you to know that an execution profiler (like gprof) does exactly what you're asking about - it tracks the amount of time spent executing each function. A profiler basically works by recording the instruction pointer (IP), the address of the currently executing instruction, every 10ms or so. After the program is done running, you invoke a postprocessor that examines the list of IPs and the program, and converts those addresses into function names. So I'd suggest just using the instruction pointer, rather than the function name, both because it's easier to code and because it's more efficient to work with a single number than with a string.