Function pointer and calling convention
Asked Answered
C

3

27
float __stdcall (*pFunc)(float a, float b) = (float (__stdcall *)(float,float))0x411280;

How to declare a function pointer with calling convention? The above gives me an error.

Congener answered 28/1, 2011 at 16:5 Comment(1)
@James It may be a calling convention may not be followed by a nested declarator.Lavonlavona
O
50

The trick is placing the __stdcall inside the parentheses like this:

float (__stdcall *pFunc)(float a, float b) = (float (__stdcall *)(float,float))0x411280;

Of course, you are recommended to use a typedef instead, but the same trick applies:

typedef float (__stdcall *FuncType)(float a, float b);
Oyer answered 28/1, 2011 at 16:55 Comment(3)
Correct me if I'm wrong, but don't we we want typedef float (__stdcall *FuncType)(float a, float b)?Phio
This does not work using GCC compiler.Scotism
Borland Delphi compiler generates this C++ header: float __stdcall (* pFunc)(float a, float b)Spurge
S
2

For a regular function, you can usually do:

__cdecl const int func();
__cdecl const int (func)();
const __cdecl int func();
const int __cdecl func();
const int (__cdecl func)();
__cdecl const __cdecl int (__cdecl func)();

It is implementation defined whether or not a compiler will accept all of these forms. Clang does. To me, the 5th version makes the most semantic sense, because it is a property of the function and not the return type alone.

You can do all of this with __attribute__((cdecl)) instead of __cdecl, which can also be used after the function, unlike __cdecl

const int (__cdecl func)() __attribute__((cdecl));

Now, to declare a constant pointer pfunc to a function with a specific calling convention:

__cdecl const int (*const pfunc)();
const __cdecl int (*const pfunc)();
const int __cdecl (*const pfunc)();
const int (__cdecl *const pfunc)();
const int (*const __cdecl pfunc)();
const int (*__cdecl const pfunc)();
__cdecl const __cdecl int (__cdecl *const pfunc)();
const int (*const pfunc)() __attribute__((cdecl));

Note that const has to be after the asterisk as usual. With double function pointers, the pointers can go anywhere with respect to the calling convention, but you have to put it in the correct place with respect to const.

Again, it is implementation defined as to what form a compiler accepts. Clang accepts all forms and correctly interprets them as the type const int (*const)() __attribute__((cdecl))

Stomach answered 29/5, 2020 at 21:50 Comment(2)
I've tried every single combination of the above to try to get the GCC compiler to recognise a function pointer typedef that specifies the __cdecl calling convention, For example: typedef void* (__cdecl *byte_array_alloc_fn)(int count) which compiles using MSVC, but produces errors in GCC.Scotism
@TimCalladene off the top of my head I would assume that it's because it does nothing in x64 code: https://mcmap.net/q/505952/-writing-a-microsoft-fastcall-64-bit-assembly-function (on MSVC it appears to override the /Gv compiler option if enabled. Also, you have to use __attribute__((cdecl)) on gccStomach
G
-1

__fastcall is the optimized one (fastest calling convention) but not used for an unknown reason

Try:

int (__fastcall *myfunction)(int,float);
Gentlemanfarmer answered 28/1, 2011 at 23:58 Comment(1)
You should have had a look at what these unknown reasons are before posting, and eventually asked a new question if it hadn't already been asked. This site is supposed to be about sharing knowledge, not suppositions.Paludal

© 2022 - 2024 — McMap. All rights reserved.