Why do compilers behave differently when static_cast(ing) a function to void*?Why can't I cast a function pointer to (void *)?What are the differences between a pointer variable and a reference variable in C++?Why use static_cast<int>(x) instead of (int)x?When should static_cast, dynamic_cast, const_cast and reinterpret_cast be used?Static constant string (class member)Why does flowing off the end of a non-void function without returning a value not produce a compiler error?Why do we need virtual functions in C++?What does int argc, char *argv[] mean?Why is the new operator allowed to return *void to every pointer-type?Implementation of static_cast operator and it's limitsWhy deleting void* is UB rather than compilation error?

Multiplicative persistence

The screen of my macbook suddenly broken down how can I do to recover

How can "mimic phobia" be cured or prevented?

How should I respond when I lied about my education and the company finds out through background check?

Are the IPv6 address space and IPv4 address space completely disjoint?

WiFi Thermostat, No C Terminal on Furnace

Loading commands from file

Electoral considerations aside, what are potential benefits, for the US, of policy changes proposed by the tweet recognizing Golan annexation?

What is Cash Advance APR?

Creature in Shazam mid-credits scene?

Open a doc from terminal, but not by its name

Calculating Wattage for Resistor in High Frequency Application?

Which one is correct as adjective “protruding” or “protruded”?

How can Trident be so inexpensive? Will it orbit Triton or just do a (slow) flyby?

Is there a working SACD iso player for Ubuntu?

Biological Blimps: Propulsion

why `nmap 192.168.1.97` returns less services than `nmap 127.0.0.1`?

Delivering sarcasm

Why should universal income be universal?

Creepy dinosaur pc game identification

What was the exact wording from Ivanhoe of this advice on how to free yourself from slavery?

Not using 's' for he/she/it

Why Shazam when there is already Superman?

Why does the Sun have different day lengths, but not the gas giants?



Why do compilers behave differently when static_cast(ing) a function to void*?


Why can't I cast a function pointer to (void *)?What are the differences between a pointer variable and a reference variable in C++?Why use static_cast<int>(x) instead of (int)x?When should static_cast, dynamic_cast, const_cast and reinterpret_cast be used?Static constant string (class member)Why does flowing off the end of a non-void function without returning a value not produce a compiler error?Why do we need virtual functions in C++?What does int argc, char *argv[] mean?Why is the new operator allowed to return *void to every pointer-type?Implementation of static_cast operator and it's limitsWhy deleting void* is UB rather than compilation error?













8















The following code compiles without any error in VSC++2017 and doesn't compile in gcc 7.3.0 (error: invalid static_cast from type ‘int(int)’ to type ‘void*’
void* p = static_cast<void*>(func)
)



#include <iostream>

int func(int x) return 2 * x;

int main()

void* p = static_cast<void*>(func);
return 0;










share|improve this question



















  • 1





    Function pointers are a bit weird. I'd have to go Standard diving, but I'm pretty sure MSVC is bending the Standard for their own nefarious purposes.

    – user4581301
    3 hours ago











  • Potential Dupe: stackoverflow.com/questions/36645660/…

    – user4581301
    3 hours ago











  • @user4581301 Not really – the other question is about C, and there might be differences in the languages...

    – Aconcagua
    3 hours ago






  • 1





    While function pointers are different animals than object pointers, most incompatibilities occur when the sizeof() the two differ. If they are the same you can usually safely convert back and forth to a void*. Even so, while it may work, it's not portable and just one of those things best avoided.

    – doug
    3 hours ago















8















The following code compiles without any error in VSC++2017 and doesn't compile in gcc 7.3.0 (error: invalid static_cast from type ‘int(int)’ to type ‘void*’
void* p = static_cast<void*>(func)
)



#include <iostream>

int func(int x) return 2 * x;

int main()

void* p = static_cast<void*>(func);
return 0;










share|improve this question



















  • 1





    Function pointers are a bit weird. I'd have to go Standard diving, but I'm pretty sure MSVC is bending the Standard for their own nefarious purposes.

    – user4581301
    3 hours ago











  • Potential Dupe: stackoverflow.com/questions/36645660/…

    – user4581301
    3 hours ago











  • @user4581301 Not really – the other question is about C, and there might be differences in the languages...

    – Aconcagua
    3 hours ago






  • 1





    While function pointers are different animals than object pointers, most incompatibilities occur when the sizeof() the two differ. If they are the same you can usually safely convert back and forth to a void*. Even so, while it may work, it's not portable and just one of those things best avoided.

    – doug
    3 hours ago













8












8








8








The following code compiles without any error in VSC++2017 and doesn't compile in gcc 7.3.0 (error: invalid static_cast from type ‘int(int)’ to type ‘void*’
void* p = static_cast<void*>(func)
)



#include <iostream>

int func(int x) return 2 * x;

int main()

void* p = static_cast<void*>(func);
return 0;










share|improve this question
















The following code compiles without any error in VSC++2017 and doesn't compile in gcc 7.3.0 (error: invalid static_cast from type ‘int(int)’ to type ‘void*’
void* p = static_cast<void*>(func)
)



#include <iostream>

int func(int x) return 2 * x;

int main()

void* p = static_cast<void*>(func);
return 0;







c++ function-pointers void-pointers static-cast






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 3 hours ago









Fabio Turati

2,63452341




2,63452341










asked 4 hours ago









Soulimane MammarSoulimane Mammar

521413




521413







  • 1





    Function pointers are a bit weird. I'd have to go Standard diving, but I'm pretty sure MSVC is bending the Standard for their own nefarious purposes.

    – user4581301
    3 hours ago











  • Potential Dupe: stackoverflow.com/questions/36645660/…

    – user4581301
    3 hours ago











  • @user4581301 Not really – the other question is about C, and there might be differences in the languages...

    – Aconcagua
    3 hours ago






  • 1





    While function pointers are different animals than object pointers, most incompatibilities occur when the sizeof() the two differ. If they are the same you can usually safely convert back and forth to a void*. Even so, while it may work, it's not portable and just one of those things best avoided.

    – doug
    3 hours ago












  • 1





    Function pointers are a bit weird. I'd have to go Standard diving, but I'm pretty sure MSVC is bending the Standard for their own nefarious purposes.

    – user4581301
    3 hours ago











  • Potential Dupe: stackoverflow.com/questions/36645660/…

    – user4581301
    3 hours ago











  • @user4581301 Not really – the other question is about C, and there might be differences in the languages...

    – Aconcagua
    3 hours ago






  • 1





    While function pointers are different animals than object pointers, most incompatibilities occur when the sizeof() the two differ. If they are the same you can usually safely convert back and forth to a void*. Even so, while it may work, it's not portable and just one of those things best avoided.

    – doug
    3 hours ago







1




1





Function pointers are a bit weird. I'd have to go Standard diving, but I'm pretty sure MSVC is bending the Standard for their own nefarious purposes.

– user4581301
3 hours ago





Function pointers are a bit weird. I'd have to go Standard diving, but I'm pretty sure MSVC is bending the Standard for their own nefarious purposes.

– user4581301
3 hours ago













Potential Dupe: stackoverflow.com/questions/36645660/…

– user4581301
3 hours ago





Potential Dupe: stackoverflow.com/questions/36645660/…

– user4581301
3 hours ago













@user4581301 Not really – the other question is about C, and there might be differences in the languages...

– Aconcagua
3 hours ago





@user4581301 Not really – the other question is about C, and there might be differences in the languages...

– Aconcagua
3 hours ago




1




1





While function pointers are different animals than object pointers, most incompatibilities occur when the sizeof() the two differ. If they are the same you can usually safely convert back and forth to a void*. Even so, while it may work, it's not portable and just one of those things best avoided.

– doug
3 hours ago





While function pointers are different animals than object pointers, most incompatibilities occur when the sizeof() the two differ. If they are the same you can usually safely convert back and forth to a void*. Even so, while it may work, it's not portable and just one of those things best avoided.

– doug
3 hours ago












1 Answer
1






active

oldest

votes


















5














Functions are implicitly convertible only to function pointers. A function pointer is not a pointer in the strict meaning of the word in the language, which refers only to pointers to objects.



Function pointers cannot be converted to void* using static_cast. The shown program is ill-formed. If a compiler does not warn, then it fails to conform to the standard. Failing to compile an ill-formed program does not violate the standard.




On systems where void* is guaranteed to be able to point to a function (such as POSIX), you can use reinterpret_cast instead:



void* p = reinterpret_cast<void*>(func);


But this is not portable to systems that lack the guarantee. (I know of no system that has a C++ compiler and does not have this guarantee, but that does not mean such system does not exist).



Standard quote:




[expr.reinterpret.cast]



Converting a function pointer to an object pointer type or vice versa is conditionally-supported. The meaning
of such a conversion is implementation-defined, except that if an implementation supports conversions in both
directions, converting a prvalue of one type to the other type and back, possibly with different cv-qualification,
shall yield the original pointer value.




Note that this conditional support does not extend to pointers to member functions. Pointers to member functions are not function pointers.






share|improve this answer




















  • 1





    POSIX requires interconvertibility between function pointers (code addresses) and object pointers (data addresses), it's necessary to make dlsym work.

    – Ben Voigt
    3 hours ago











  • @BenVoigt - that's true, but it won't be done with static_cast. It can be done with reinterpret_cast or a C-style cast.

    – Peter
    2 hours ago











  • On this answer - the standard says nothing about "warnings". The standard requires diagnostics if a program is ill-formed and the error message in the question represents a diagnostic. But the standard neither requires nor forbids warnings (messages about suspicious constructs, etc, that do not prevent code from compiling) - they are discretionary features offered by implementations (and often an indicator of "quality of implementation"). Their absence does not indicate non-compliance with the standard.

    – Peter
    2 hours ago











  • @Peter the standard requires a diagnostic if the program is ill-formed (unless specified otherwise). The shown program is ill-formed. A diagnostic is required. A warning is a form of a diagnostic, and issuing a warning would be sufficient to conform to the standard. Lack of a diagnostic is violation of the standard.

    – eerorika
    2 hours ago











Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55319602%2fwhy-do-compilers-behave-differently-when-static-casting-a-function-to-void%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









5














Functions are implicitly convertible only to function pointers. A function pointer is not a pointer in the strict meaning of the word in the language, which refers only to pointers to objects.



Function pointers cannot be converted to void* using static_cast. The shown program is ill-formed. If a compiler does not warn, then it fails to conform to the standard. Failing to compile an ill-formed program does not violate the standard.




On systems where void* is guaranteed to be able to point to a function (such as POSIX), you can use reinterpret_cast instead:



void* p = reinterpret_cast<void*>(func);


But this is not portable to systems that lack the guarantee. (I know of no system that has a C++ compiler and does not have this guarantee, but that does not mean such system does not exist).



Standard quote:




[expr.reinterpret.cast]



Converting a function pointer to an object pointer type or vice versa is conditionally-supported. The meaning
of such a conversion is implementation-defined, except that if an implementation supports conversions in both
directions, converting a prvalue of one type to the other type and back, possibly with different cv-qualification,
shall yield the original pointer value.




Note that this conditional support does not extend to pointers to member functions. Pointers to member functions are not function pointers.






share|improve this answer




















  • 1





    POSIX requires interconvertibility between function pointers (code addresses) and object pointers (data addresses), it's necessary to make dlsym work.

    – Ben Voigt
    3 hours ago











  • @BenVoigt - that's true, but it won't be done with static_cast. It can be done with reinterpret_cast or a C-style cast.

    – Peter
    2 hours ago











  • On this answer - the standard says nothing about "warnings". The standard requires diagnostics if a program is ill-formed and the error message in the question represents a diagnostic. But the standard neither requires nor forbids warnings (messages about suspicious constructs, etc, that do not prevent code from compiling) - they are discretionary features offered by implementations (and often an indicator of "quality of implementation"). Their absence does not indicate non-compliance with the standard.

    – Peter
    2 hours ago











  • @Peter the standard requires a diagnostic if the program is ill-formed (unless specified otherwise). The shown program is ill-formed. A diagnostic is required. A warning is a form of a diagnostic, and issuing a warning would be sufficient to conform to the standard. Lack of a diagnostic is violation of the standard.

    – eerorika
    2 hours ago
















5














Functions are implicitly convertible only to function pointers. A function pointer is not a pointer in the strict meaning of the word in the language, which refers only to pointers to objects.



Function pointers cannot be converted to void* using static_cast. The shown program is ill-formed. If a compiler does not warn, then it fails to conform to the standard. Failing to compile an ill-formed program does not violate the standard.




On systems where void* is guaranteed to be able to point to a function (such as POSIX), you can use reinterpret_cast instead:



void* p = reinterpret_cast<void*>(func);


But this is not portable to systems that lack the guarantee. (I know of no system that has a C++ compiler and does not have this guarantee, but that does not mean such system does not exist).



Standard quote:




[expr.reinterpret.cast]



Converting a function pointer to an object pointer type or vice versa is conditionally-supported. The meaning
of such a conversion is implementation-defined, except that if an implementation supports conversions in both
directions, converting a prvalue of one type to the other type and back, possibly with different cv-qualification,
shall yield the original pointer value.




Note that this conditional support does not extend to pointers to member functions. Pointers to member functions are not function pointers.






share|improve this answer




















  • 1





    POSIX requires interconvertibility between function pointers (code addresses) and object pointers (data addresses), it's necessary to make dlsym work.

    – Ben Voigt
    3 hours ago











  • @BenVoigt - that's true, but it won't be done with static_cast. It can be done with reinterpret_cast or a C-style cast.

    – Peter
    2 hours ago











  • On this answer - the standard says nothing about "warnings". The standard requires diagnostics if a program is ill-formed and the error message in the question represents a diagnostic. But the standard neither requires nor forbids warnings (messages about suspicious constructs, etc, that do not prevent code from compiling) - they are discretionary features offered by implementations (and often an indicator of "quality of implementation"). Their absence does not indicate non-compliance with the standard.

    – Peter
    2 hours ago











  • @Peter the standard requires a diagnostic if the program is ill-formed (unless specified otherwise). The shown program is ill-formed. A diagnostic is required. A warning is a form of a diagnostic, and issuing a warning would be sufficient to conform to the standard. Lack of a diagnostic is violation of the standard.

    – eerorika
    2 hours ago














5












5








5







Functions are implicitly convertible only to function pointers. A function pointer is not a pointer in the strict meaning of the word in the language, which refers only to pointers to objects.



Function pointers cannot be converted to void* using static_cast. The shown program is ill-formed. If a compiler does not warn, then it fails to conform to the standard. Failing to compile an ill-formed program does not violate the standard.




On systems where void* is guaranteed to be able to point to a function (such as POSIX), you can use reinterpret_cast instead:



void* p = reinterpret_cast<void*>(func);


But this is not portable to systems that lack the guarantee. (I know of no system that has a C++ compiler and does not have this guarantee, but that does not mean such system does not exist).



Standard quote:




[expr.reinterpret.cast]



Converting a function pointer to an object pointer type or vice versa is conditionally-supported. The meaning
of such a conversion is implementation-defined, except that if an implementation supports conversions in both
directions, converting a prvalue of one type to the other type and back, possibly with different cv-qualification,
shall yield the original pointer value.




Note that this conditional support does not extend to pointers to member functions. Pointers to member functions are not function pointers.






share|improve this answer















Functions are implicitly convertible only to function pointers. A function pointer is not a pointer in the strict meaning of the word in the language, which refers only to pointers to objects.



Function pointers cannot be converted to void* using static_cast. The shown program is ill-formed. If a compiler does not warn, then it fails to conform to the standard. Failing to compile an ill-formed program does not violate the standard.




On systems where void* is guaranteed to be able to point to a function (such as POSIX), you can use reinterpret_cast instead:



void* p = reinterpret_cast<void*>(func);


But this is not portable to systems that lack the guarantee. (I know of no system that has a C++ compiler and does not have this guarantee, but that does not mean such system does not exist).



Standard quote:




[expr.reinterpret.cast]



Converting a function pointer to an object pointer type or vice versa is conditionally-supported. The meaning
of such a conversion is implementation-defined, except that if an implementation supports conversions in both
directions, converting a prvalue of one type to the other type and back, possibly with different cv-qualification,
shall yield the original pointer value.




Note that this conditional support does not extend to pointers to member functions. Pointers to member functions are not function pointers.







share|improve this answer














share|improve this answer



share|improve this answer








edited 1 hour ago

























answered 3 hours ago









eerorikaeerorika

87.2k663134




87.2k663134







  • 1





    POSIX requires interconvertibility between function pointers (code addresses) and object pointers (data addresses), it's necessary to make dlsym work.

    – Ben Voigt
    3 hours ago











  • @BenVoigt - that's true, but it won't be done with static_cast. It can be done with reinterpret_cast or a C-style cast.

    – Peter
    2 hours ago











  • On this answer - the standard says nothing about "warnings". The standard requires diagnostics if a program is ill-formed and the error message in the question represents a diagnostic. But the standard neither requires nor forbids warnings (messages about suspicious constructs, etc, that do not prevent code from compiling) - they are discretionary features offered by implementations (and often an indicator of "quality of implementation"). Their absence does not indicate non-compliance with the standard.

    – Peter
    2 hours ago











  • @Peter the standard requires a diagnostic if the program is ill-formed (unless specified otherwise). The shown program is ill-formed. A diagnostic is required. A warning is a form of a diagnostic, and issuing a warning would be sufficient to conform to the standard. Lack of a diagnostic is violation of the standard.

    – eerorika
    2 hours ago













  • 1





    POSIX requires interconvertibility between function pointers (code addresses) and object pointers (data addresses), it's necessary to make dlsym work.

    – Ben Voigt
    3 hours ago











  • @BenVoigt - that's true, but it won't be done with static_cast. It can be done with reinterpret_cast or a C-style cast.

    – Peter
    2 hours ago











  • On this answer - the standard says nothing about "warnings". The standard requires diagnostics if a program is ill-formed and the error message in the question represents a diagnostic. But the standard neither requires nor forbids warnings (messages about suspicious constructs, etc, that do not prevent code from compiling) - they are discretionary features offered by implementations (and often an indicator of "quality of implementation"). Their absence does not indicate non-compliance with the standard.

    – Peter
    2 hours ago











  • @Peter the standard requires a diagnostic if the program is ill-formed (unless specified otherwise). The shown program is ill-formed. A diagnostic is required. A warning is a form of a diagnostic, and issuing a warning would be sufficient to conform to the standard. Lack of a diagnostic is violation of the standard.

    – eerorika
    2 hours ago








1




1





POSIX requires interconvertibility between function pointers (code addresses) and object pointers (data addresses), it's necessary to make dlsym work.

– Ben Voigt
3 hours ago





POSIX requires interconvertibility between function pointers (code addresses) and object pointers (data addresses), it's necessary to make dlsym work.

– Ben Voigt
3 hours ago













@BenVoigt - that's true, but it won't be done with static_cast. It can be done with reinterpret_cast or a C-style cast.

– Peter
2 hours ago





@BenVoigt - that's true, but it won't be done with static_cast. It can be done with reinterpret_cast or a C-style cast.

– Peter
2 hours ago













On this answer - the standard says nothing about "warnings". The standard requires diagnostics if a program is ill-formed and the error message in the question represents a diagnostic. But the standard neither requires nor forbids warnings (messages about suspicious constructs, etc, that do not prevent code from compiling) - they are discretionary features offered by implementations (and often an indicator of "quality of implementation"). Their absence does not indicate non-compliance with the standard.

– Peter
2 hours ago





On this answer - the standard says nothing about "warnings". The standard requires diagnostics if a program is ill-formed and the error message in the question represents a diagnostic. But the standard neither requires nor forbids warnings (messages about suspicious constructs, etc, that do not prevent code from compiling) - they are discretionary features offered by implementations (and often an indicator of "quality of implementation"). Their absence does not indicate non-compliance with the standard.

– Peter
2 hours ago













@Peter the standard requires a diagnostic if the program is ill-formed (unless specified otherwise). The shown program is ill-formed. A diagnostic is required. A warning is a form of a diagnostic, and issuing a warning would be sufficient to conform to the standard. Lack of a diagnostic is violation of the standard.

– eerorika
2 hours ago






@Peter the standard requires a diagnostic if the program is ill-formed (unless specified otherwise). The shown program is ill-formed. A diagnostic is required. A warning is a form of a diagnostic, and issuing a warning would be sufficient to conform to the standard. Lack of a diagnostic is violation of the standard.

– eerorika
2 hours ago




















draft saved

draft discarded
















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55319602%2fwhy-do-compilers-behave-differently-when-static-casting-a-function-to-void%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Are there any AGPL-style licences that require source code modifications to be public? Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30pm US/Eastern) Announcing the arrival of Valued Associate #679: Cesar Manara Unicorn Meta Zoo #1: Why another podcast?Force derivative works to be publicAre there any GPL like licenses for Apple App Store?Do you violate the GPL if you provide source code that cannot be compiled?GPL - is it distribution to use libraries in an appliance loaned to customers?Distributing App for free which uses GPL'ed codeModifications of server software under GPL, with web/CLI interfaceDoes using an AGPLv3-licensed library prevent me from dual-licensing my own source code?Can I publish only select code under GPLv3 from a private project?Is there published precedent regarding the scope of covered work that uses AGPL software?If MIT licensed code links to GPL licensed code what should be the license of the resulting binary program?If I use a public API endpoint that has its source code licensed under AGPL in my app, do I need to disclose my source?

2013 GY136 Descoberta | Órbita | Referências Menu de navegação«List Of Centaurs and Scattered-Disk Objects»«List of Known Trans-Neptunian Objects»

Button changing it's text & action. Good or terrible? The 2019 Stack Overflow Developer Survey Results Are Inchanging text on user mouseoverShould certain functions be “hard to find” for powerusers to discover?Custom liking function - do I need user login?Using different checkbox style for different checkbox behaviorBest Practices: Save and Exit in Software UIInteraction with remote validated formMore efficient UI to progress the user through a complicated process?Designing a popup notice for a gameShould bulk-editing functions be hidden until a table row is selected, or is there a better solution?Is it bad practice to disable (replace) the context menu?