6 ms·
and various dialects that people believe are C. To be fair, the SO question specifies "using C or C++", not just C.
by chops 16y ago
and various dialects that people believe are C.
To be fair, the SO question specifies "using C or C++", not just C.
- RiderOfGiraffes 16y agoTrue. At a glance I'm suspicious that some might truly be in neither, but I'm not really bothered to check. Any Language Lawyers around?
- nathanb 16y agoWithout specifying dialect (ANSI C, C99, etc.), I believe "valid C" really only means "some C compiler somewhere will accept it without generating errors".
- TillE 16y agoSomeone claims the second answer "obviously" isn't C, which I don't understand. GCC 4.5.2 compiles it without complaint. Is pointer arithmetic not allowed? Or calling main()?
- tspiteri 16y agoI'm not sure pointer arithmetic on function pointers is standard C. Using the -pedantic flag, gcc 4.5.2 does give a "warning: pointer to a function used in subtraction".
- emillon 16y agoThe paragraph on pointer differences (ANSI C99 6.5.6§9) states that : "both shall point to elements of the same array object, or one past the last element of the array object […] The size of the result is implementation-defined, and its type (a signed integer type) is ptrdiff_t". So, for an array of function pointer that would be legal behaviour, but for pointers to plain functions, it is undefined behaviour.
- nitrogen 16y agoWhen I was in high school I thought I could implement shared libraries for DOS/DJGPP by subtracting function pointers to each function I wanted to export and dumping the intervening data to disk. I quickly realized that the code was not position independent, and that other segments (like strings) were not being exported. I also discovered Linux, and thus abandoned the idea.
- silentbicycle 16y agoIt has to do with getting an int from pointer arithmetic on function pointers. IIRC, there's no guarantee that a function pointer will even fit in any specific kind of int. On this computer, sizeof(&main) is 8, sizeof(int) is 4.
- JoachimSchipper 16y agoFunction pointers are all kinds of iffy - you can't translate them to void *, for instance (this makes total sense if you consider the fact that C programs may run on embedded devices with separate RAM/ROM addressing schemes). I'm not sure about arithmetic, but I'd expect it to be undefined. If you do want to put a (non-function) pointer into an integer, convert to (C99) [u]intptr_t. Of course, that does not have to be defined...
- NickPollard 16y agoReally? I didn't know that. Shows how much I have still to learn about C. A program I'm writing now uses void* as a generic function pointer, which I cast to different function signatures as required depending on usage. I'm guessing that's considered harmful, is there a better or more idiomatic way to do this?
- kragen 16y agoI believe there is not a standard way to do what you are doing. However, in common implementations of C, you'll only have trouble if some of your functions have a different calling convention than others — stdcall, say, or fastcall, or Pascal calling convention, or far vs. near calls on 16-bit x86. I assume you can avoid that with a union with one member for each calling convention, but I've never tried it. Architectures where code pointers are bigger than data pointers are fairly exotic, I think. The AS/400 might be an example, I'm not sure. However! You can avoid that particular problem by using (void* )(void) as your generic function pointer type, rather than simply void *.
- JoachimSchipper 16y agoPretty much the only standard way to do this involves something like "void (fp)(void arg)" or "void (*fp)(va_list ap)" and generous casting. That said, this is not that likely to be a problem in practice on Unix machines (Windows has more than one calling convention - I have no idea how much of a problem that is.)
- acqq 16y agoSubtracting function pointers doesn't have to have any meaning. Tiny C (from 2006, 5 years old) gives: function pointer expected MS C 6 (from 1998, 13 years old) gives error C2296: '-' : illegal, left operand has type 'void (__cdecl *)(int )' Turbo C 2.01 (from 1988, 23 years old) gives: Size of structure or array not known in function etc. I think the really clean solution (as far as I know, at least it works with all the compilers I've mentioned) is: http://news.ycombinator.com/item?id=2323771 http://news.ycombinator.com/item?id=2323771
- derleth 16y agoAnything that has 'void main' isn't quite up to snuff, to begin with.