2

Writing a library that works with function callbacks, I've frequently type-casted (and called) function pointers to types with the same calling convention and same signatures, but with one exception: they had parameters pointing to different types (all data), or void pointers.

Recently, I discovered that it might not be that safe, according to this: https://stackoverflow.com/a/14044244/3079266

Basically, as I understood it, if the types of the arguments are compatible, that means the function pointer types are also compatible, and there should be no problem.

Now, I've got 3 questions.

First: does this mean that, since pointers to different types are technically incompatible, what I am doing can cause undefined behaviour?

Second: where (on what architectures) can I get away with it? Are Windows x86 or x64 versions among them?

Third: where can I NOT get away with it?

Community
  • 1
  • 1
  • @iharob But the function pointers you pass to those functions *must* take `void` pointers or you have undefined behavior. It's okay to cast the pointers inside the functions, but the arguments should be as specified. – Some programmer dude Jan 04 '15 at 16:05
  • 4
    First question: yes. Second question: everywhere. Third question: nowhere (except for when you're answering SO questions, people here love UB and down-vote you if you don't mention it where needed). – barak manos Jan 04 '15 at 16:05
  • @barakmanos: so, I should probably just warn users that _technically_, this can cause UB, but in reality won't? Thanks! =) –  Jan 04 '15 at 16:10
  • Well, I don't quite understand why you're not using the exact function prototype to begin with. – barak manos Jan 04 '15 at 16:11
  • @barakmanos: that's a bit too long a story to explain in an SO comment, and it's not really interesting =) –  Jan 04 '15 at 16:15
  • @barakmanos: That's nearly accurate. We are moving there, but it's still a few decades yet, at least. – Deduplicator Jan 04 '15 at 16:19
  • Are you asking strictly about C, or do you care about C++ also? Because multiple inheritance can break this. Other than that, compiler optimizations can kick you in the sack in surprising ways if you trigger UB, even in apparently harmless cases like this. Remember when [SPEC2006 broke with gcc 4.8.0](http://blog.regehr.org/archives/918)? – Wintermute Jan 04 '15 at 16:36

1 Answers1

2
  1. Yes, this is UB by itself
  2. You probably can get away with this in non-optimized non-debug builds. An optimizer may take advantage of pointer types to figure out whether two pointers can be aliased, logic which may fail if you're lying about the actual types. Debug builds of course can just check outright if there's a type mismatch.
  3. Windows is not a compiler, so that's not a sensible question as-is. Common Windows compilers do optimize builds, and ICC especially is known to have advanced optimizations.
MSalters
  • 173,980
  • 10
  • 155
  • 350