For some chips, like xstormy16 and m16c, function pointers are wider than other pointers. These types of chips can use thunks to get around this for gcc, but there are still a few cases when you want to know the real (>16 bit) address of the function (reset vectors, for example).
If you use code like this: long x = (long) &main; (long long suffices for 32 bit machines, or -m32 on x86_64) You stumble across two problems. First, the tree for this has not one but two conversions, so this code in varasm.c: case CONVERT_EXPR: case NOP_EXPR: { tree src; tree src_type; tree dest_type; src = TREE_OPERAND (value, 0); src_type = TREE_TYPE (src); dest_type = TREE_TYPE (value); needs to look something like this: src = TREE_OPERAND (value, 0); while (TREE_CODE (src) == CONVERT_EXPR || TREE_CODE (src) == NOP_EXPR) src = TREE_OPERAND (src, 0); Once past that, there's a second bit of code in varasm.c (output_constant): thissize = int_size_in_bytes (TREE_TYPE (exp)); Which means the example code gets assembled like this (for example): .short main .zero 2 What we need, however, is this: .long main First, this allows the linker to put in the real address of main rather than the 16 bit thunk, and second, the code in output_constant() always puts the zeros after the short, even on big endian machines (visual inspection, not tested). Ideas?