I'll write my suggestion as an answer and whore for some reputation :-)
You need to explicitly cast the data pointer into a function pointer. With a typedef for the appropriate function pointer, you can do so without making the code too hard to read:
char shellcode[] =
"\x31\xc0"
"\xb0\x01"
"\x31\xdb"
"\xcd\x80";
typedef void (*SHELLCODE)(void);
int main() {
SHELLCODE func = (SHELLCODE) shellcode;
func();
/* ...and this will work as well, which some might find more readable: */
((SHELLCODE) shellcode)();
return 0;
}
This compiles cleanly with clang 1.1, but GCC 4.4.3 will still give you a warning about the pointer conversion -- although now it is a more precise warning:
$ gcc -Wall -Wextra -ansi -pedantic shellcode.c
shellcode.c: In function ‘main’:
shellcode.c:10: warning: ISO C forbids conversion of object pointer to function pointer type
shellcode.c:14: warning: ISO C forbids conversion of object pointer to function pointer type
Skipping the "-pedantic" flag will make it compile cleanly with GCC too, but who ever does that seriously?