On 04/23/2018 08:11 AM, kmo wrote:
> Please consider the following code:
>
> CODE START----------------------------------------
>
> #include<stdio.h>
>
> int f1(int, int);
> int f2(int, int);
> int f3(int);
>
> template<typename T, T *ptr>
> inline void *fid() {
> return (void *)&fid<T, ptr>;
> };
>
> int main() {
> printf("%p\n", fid<decltype(f1), f1>());
Note 1: "%p" requires a void* argument. On many systems, all pointers
are interchangeable, so it doesn't matter, but the C++ standard doesn't
require this.
Note 2: 7.11p2 defines the conversion from a pointer to an object type
to a void*. There's no corresponding clause describing conversion from a
pointer to a function type to a void*, except 7.11p1, which only applies
to null pointers. The behavior of converting a non-null pointer to a
function to void* so it can be used by printf("%p") is therefore
undefined by omission of an explicit definition (3.27).
The best you can do with function pointer is to store in in an pointer
object, and then print a hex dump of the bytes that make up the pointer.
In practice, such code has good chance of working as you expect it to,
particularly if you're using a POSIX-compliant system: dlsym() can only
work as it's supposed to if the function pointers it works with can be
safely converted to and from void*. That doesn't guarantee that any
other function pointers can be safely converted, but it does make it
more likely.
> printf("%p\n", fid<decltype(f2), f2>());
> printf("%p\n", fid<decltype(f3), f3>());
> return 0;
> };
>
> CODE END------------------------------------------
>
>
> fid takes a function pointer as template parameter and returns the pointer to
> itself, making a kind of numeric identifer of a declaration.
> This is the entire source code, no additonal files are present.
> f1, f2, f3 are only delcared here, no definition is given.
>
> The question is:
> a) is this code valid (should this code compile)?
> b) if it is, what should it output: are three different pointers guaranteed?
> c) if it is not, why?
> Or, maybe, it is a some case of undefined behavior / no diagnostics required?
>
> My reasoning goes this way:
> Main question: Are f1, f2, f3 ODR used?
"A function whose name appears as a potentially-evaluated expression is
odr-used if it is the unique lookup result or the selected member of a
set of overloaded functions (6.4, 16.3, 16.4), unless it is a pure
virtual function and either its name is not explicitly qualified or the
expression forms a pointer to member (8.3.1)."
f1, f2, and f3 are the unique lookup results, so that clause should
apply - there are no overloaded or pure virtual functions involved, so
none of the exceptions apply.
> If yes, the code sould not compile.
I think it should compile - but what it should not do is link.