Address of Function Is Not Actual Code Address

Address of function is not actual code address

That is caused by 'Incremental Linking'. If you disable that in your compiler/linker settings the jumps will go away.

http://msdn.microsoft.com/en-us/library/4khtbfyf(VS.80).aspx

c++ function addresses coming out different in attached profiler library than in the subject code base

I think it is because of Incremental Linking. When it is turned on, you'll get an Incremental Linking Table (ILT). ILT contains a jump table. When a function is called, it is called via this ILT.

In FuncTable, you'll get an address which is in ILT, it won't be the address of the actual function. But in _penter, its return address will be the actual function (this is what is put in pCaller).

Turn off incremental linking, and you'll be fine.

How to fix warning the compiler can assume that the address of 'object' will never be NULL

References are never null in a well-formed C++ program. The only valid way to initialize a reference is to bind it to a valid object. The only way a "null reference" may happen is if one derefernces a null pointer, as you have. But then the behavior of your program is undefined even before you check &object == NULL. The bug is in the code that passes the "null reference", and it must be fixed there.

So the compiler is warning you that you added a superfluous check, that protects you from little to nothing, because the broken code that needs to be fixed is outside your function.

Getting C++ Function Address using VSCode & VS

std::ostream::operator<< has an overload for bool and a pointer can be implicitly converted to a bool, so the output from VSCode (where you tell us you are compiling with mingw) is correct. Since the address of function getNumber is bound to be non-zero, this becomes true, which equals 1, when converted to a bool, so that's what gets printed.

On the other hand, MSVC (which is what Visual Studio uses to compile your code) appears to be getting it wrong.

To be sure that you output the address of the function, you can do:

cout << (void *) getNumber << endl;

Again, a specific overload for void * ensures that getNumber is then interpreted as an address.


Addendum: With a sufficiently high warning level set, gcc will warn you about this, see: https://wandbox.org/permlink/J9kxSzLshRQsdt0e

Can I take the address of a function defined in standard library?

Short answer

No.

Explanation

[namespace.std] says:

Let F denote a standard library function ([global.functions]), a standard library static member function, or an instantiation of a standard library function template.
Unless F is designated an addressable function, the behavior of a C++ program is unspecified (possibly ill-formed) if it explicitly or implicitly attempts to form a pointer to F.
[Note: Possible means of forming such pointers include application of the unary & operator ([expr.unary.op]), addressof ([specialized.addressof]), or a function-to-pointer standard conversion ([conv.func]).
— end note ]
Moreover, the behavior of a C++ program is unspecified (possibly ill-formed) if it attempts to form a reference to F or if it attempts to form a pointer-to-member designating either a standard library non-static member function ([member.functions]) or an instantiation of a standard library member function template.

With this in mind, let's check the two calls to std::invoke.

The first call

std::invoke(std::boolalpha, std::cout);

Here, we are attempting to form a pointer to std::boolalpha. Fortunately, [fmtflags.manip] saves the day:

Each function specified in this subclause is a designated addressable function ([namespace.std]).

And boolalpha is a function specified in this subclause.
Thus, this line is well-formed, and is equivalent to:

std::cout.setf(std::ios_base::boolalpha);

But why is that? Well, it is necessary for the following code:

std::cout << std::boolalpha;

The second call

std::cout << std::invoke(static_cast<ctype_func>(std::tolower), 'A') << "\n";

Unfortunately, [cctype.syn] says:

The contents and meaning of the header <cctype> are the same as the C standard library header <ctype.h>.

Nowhere is tolower explicitly designated an addressable function.

Therefore, the behavior of this C++ program is unspecified (possibly ill-formed), because it attempts to form a pointer to tolower, which is not designated an addressable function.

Conclusion

The expected output is not guaranteed.
In fact, the code is not even guaranteed to compile.


This also applies to member functions.
[namespace.std] doesn’t explicitly mention this, but it can be seen from [member.functions] that the behavior of a C++ program is unspecified (possibly ill-formed) if it attempts to take the address of a member function declared in the C++ standard library. Per [member.functions]/2:

For a non-virtual member function described in the C++ standard library, an implementation may declare a different set of member function signatures, provided that any call to the member function that would select an overload from the set of declarations described in this document behaves as if that overload were selected. [ Note: For instance, an implementation may add parameters with default values, or replace a member function with default arguments with two or more member functions with equivalent behavior, or add additional signatures for a member function name. — end note ]

And [expr.unary.op]/6:

The address of an overloaded function can be taken only in a context that uniquely determines which version of the overloaded function is referred to (see [over.over]). [ Note: Since the context might determine whether the operand is a static or non-static member function, the context can also affect whether the expression has type “pointer to function” or “pointer to member function”. — end note ]

Therefore, the behavior of a program is unspecified (possibly ill-formed) if it explicitly or implicitly attempts to form a pointer to a member function in the C++ library.

(Thanks for the comment for pointing this out!)

Calling a function through its address in memory in c / c++

On modern operating systems, each process has its own address space and addresses are only valid within a process. If you want to execute code in some other process, you either have to inject a shared library or attach your program as a debugger.

Once you are in the other program's address space, this code invokes a function at an arbitrary address:

typedef int func(void);
func* f = (func*)0xdeadbeef;
int i = f();

Printing Function Address

This is not correct. %p is only for object pointer types (in fact, void * specifically). There is no format specifier for a function pointer.



Related Topics



Leave a reply



Submit