Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // This example illustrates a bug in GCC, Clang and VC++,
- // which allows a pointer to function type with cv-qualifiers to be formed and used.
- #include <iostream>
- template<typename X>
- struct get_pointer
- {
- private:
- template<typename F>
- struct extract;
- template<typename F>
- struct extract<int(F)>
- {
- typedef F ptr_t;
- };
- public:
- // Function type X in an argument should become a pointer (8.3.5/5).
- // Since we later use function type that has volatile qualifier,
- // a pointer to such type is being formed here - which is prohibited,
- // see 8.3.1 note 4. This program is ill-formed.
- // Out of GCC, Clang and VC++ only VC++ generates an
- // error - but only if the argument doesn't have a name (quite strange)
- // (i.e
- // typedef int func_t(X value);
- // will actually generate an error in VC++).
- typedef int func_t(X);
- typedef typename extract<func_t>::ptr_t type;
- };
- void f() { std::cout << "x" << std::endl; }
- // volatile in function typedef is allowed.
- typedef void volatile_function_t() volatile;
- // this is the line that should cause an error but does not:
- typedef get_pointer<volatile_function_t>::type volatile_function_ptr_t;
- int main()
- {
- #ifdef __clang__ /* for Clang at least a cast is required */
- volatile_function_ptr_t z = (volatile_function_ptr_t)(&f);
- #else /* VC++ and GCC happily accept it even without a cast */
- volatile_function_ptr_t z = &f;
- #endif
- z(); // Call our volatile non-member function.
- // When compiled with Clang or VC++ a usual call to f() is generated.
- // However GCC generates incorrect code - the resulting program segfaults.
- }
Advertisement
Add Comment
Please, Sign In to add comment