views:

69

answers:

2

I'm running into a bit of a problem here, I'm messing around with machine code and function pointers, and there's a bit of my code that VC++ simply refuses to compile.

This compiles and runs exactly as expected:

#include <stdlib.h>
#include <stdio.h>

int main()
{
    char tarr[] = {0xb8, 222, 0, 0, 0, 0xc3};

    int (*testfn)() = tarr;

    printf("%d", testfn()); // prints 222

    getchar();
}

However, Visual C++ Express will not compile the following, giving this error: error C2143: syntax error : missing ';' before 'type'

#include <stdlib.h>
#include <stdio.h>

int main()
{
    char* tarr = (char*) malloc(1000);
    tarr[0] = 0xb8;
    tarr[1] = 222;
    tarr[2] = 0;
    tarr[3] = 0;
    tarr[4] = 0;
    tarr[5] = 0xc3;

    int (*testfn)() = tarr; // syntax error here

    printf("%d", testfn());

    getchar();
}

I've looked at the supposedly faulty code and I cannot see anything wrong with it. What's going on? Is there something I'm missing?

+1  A: 

The code compiles with warnings in GCC and fails to compile with G++. You're missing a cast on that line. You're also missing a return value from main.

    int (*testfn)() = (int (*)()) tarr; // no more syntax error?
Draemon
The cast doesn't really make a difference, and neither does the return value.
Charlie Somerville
Yes it does: The warning is there for a reason. On some architectures function pointers are a different size from data pointers. I always compile with -Wall. G++ actually calls it an error, so I guess C++ is stricter than C in this regard. That *is* your problem.
Draemon
@Draemon: different pointer sizes is not the only problem here - the memory region where stack and/or heap are placed might additionally be marked non-executable
Christoph
Ahh, ok. In my case I'm doing this as a little experiment, but I'll be sure to keep that in mind if I ever need to target a different architecture.
Charlie Somerville
@Christoph I'm aware of that - I've turned off NX support, etc. for this project anyway
Charlie Somerville
+2  A: 

Is this C code? If so, and it is not C99 then you need to move the declaration of testfd to before the assignments to tarr[X].

Richard Pennington
Oh cool, that worked. I didn't know I had to do that, so I'm surprised the first snippet compiled.
Charlie Somerville
The first snippit is correct for C < C99. All declarations in pre-C99 C need to occur before statements.
Richard Pennington
And both are invalid C++
Draemon
@Richard I'm not actually sure which C standard VC++ is compiling this with, I know for sure it's treating it as C code, not C++
Charlie Somerville