Hi all, I had the following function that used function pointers with void arguments, typedef void (*FP)(); void foo() { printf("hello world from foo\n"); } int main() { FP fp; fp = foo; (*fp)(); } The corresponding bitcode, with no optimizations is target datalayout "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" target triple = "x86_64-unknown-linux-gnu" @.str = private constant [21 x i8] c"hello world from foo\00", align 1 ; <[21 x i8]*> [#uses=1] define void @foo() nounwind { entry: %0 = call i32 @puts(i8* getelementptr inbounds ([21 x i8]* @.str, i64 0, i64 0)) nounwind ; <i32> [#uses=0] br label %return return: ; preds = %entry ret void } declare i32 @puts(i8*) define i32 @main() nounwind { entry: %retval = alloca i32 ; <i32*> [#uses=1] %fp = alloca void (...)* ; <void (...)**> [#uses=2] %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0] store void (...)* bitcast (void ()* @foo to void (...)*), void (...)** %fp, align 8 %0 = load void (...)** %fp, align 8 ; <void (...)*> [#uses=1] call void (...)* %0() nounwind br label %return return: ; preds = %entry %retval1 = load i32* %retval ; <i32> [#uses=1] ret i32 %retval1 } I was wondering why LLVM casts the function pointer to a varargs function?Is there some reason why it should do that? Thanks. Arushi
Do you compile this as C? In C, unlike in C++, empty parenthesis do not mean "no arguments", they mean "no prototype", which is typically treated the same way as varargs in calling conventions. To declare function with no arguments do typedef void (*FP)(void); Eugene On Wed, Apr 21, 2010 at 10:22 PM, Arushi Aggarwal <arushi987 at gmail.com> wrote:> Hi all, > > I had the following function that used function pointers with void arguments, > > > typedef void (*FP)(); > > void foo() { > printf("hello world from foo\n"); > } > int main() { > FP fp; > fp = foo; > (*fp)(); > > } > > The corresponding bitcode, with no optimizations is > > target datalayout > "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" > target triple = "x86_64-unknown-linux-gnu" > > @.str = private constant [21 x i8] c"hello world from foo\00", align 1 > ; <[21 x i8]*> [#uses=1] > > define void @foo() nounwind { > entry: > %0 = call i32 @puts(i8* getelementptr inbounds ([21 x i8]* @.str, > i64 0, i64 0)) nounwind ; <i32> [#uses=0] > br label %return > > return: ; preds = %entry > ret void > } > > declare i32 @puts(i8*) > > define i32 @main() nounwind { > entry: > %retval = alloca i32 ; <i32*> [#uses=1] > %fp = alloca void (...)* ; <void (...)**> [#uses=2] > %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0] > store void (...)* bitcast (void ()* @foo to void (...)*), void > (...)** %fp, align 8 > %0 = load void (...)** %fp, align 8 ; <void (...)*> [#uses=1] > call void (...)* %0() nounwind > br label %return > > return: ; preds = %entry > %retval1 = load i32* %retval ; <i32> [#uses=1] > ret i32 %retval1 > } > > I was wondering why LLVM casts the function pointer to a varargs > function?Is there some reason why it should do that? > > Thanks. > Arushi > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >
Thanks!. Arushi On Wed, Apr 21, 2010 at 4:34 PM, Eugene Toder <eltoder at gmail.com> wrote:> Do you compile this as C? In C, unlike in C++, empty parenthesis do > not mean "no arguments", they mean "no prototype", which is typically > treated the same way as varargs in calling conventions. To declare > function with no arguments do typedef void (*FP)(void); > > Eugene > > On Wed, Apr 21, 2010 at 10:22 PM, Arushi Aggarwal <arushi987 at gmail.com> wrote: >> Hi all, >> >> I had the following function that used function pointers with void arguments, >> >> >> typedef void (*FP)(); >> >> void foo() { >> printf("hello world from foo\n"); >> } >> int main() { >> FP fp; >> fp = foo; >> (*fp)(); >> >> } >> >> The corresponding bitcode, with no optimizations is >> >> target datalayout >> "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" >> target triple = "x86_64-unknown-linux-gnu" >> >> @.str = private constant [21 x i8] c"hello world from foo\00", align 1 >> ; <[21 x i8]*> [#uses=1] >> >> define void @foo() nounwind { >> entry: >> %0 = call i32 @puts(i8* getelementptr inbounds ([21 x i8]* @.str, >> i64 0, i64 0)) nounwind ; <i32> [#uses=0] >> br label %return >> >> return: ; preds = %entry >> ret void >> } >> >> declare i32 @puts(i8*) >> >> define i32 @main() nounwind { >> entry: >> %retval = alloca i32 ; <i32*> [#uses=1] >> %fp = alloca void (...)* ; <void (...)**> [#uses=2] >> %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0] >> store void (...)* bitcast (void ()* @foo to void (...)*), void >> (...)** %fp, align 8 >> %0 = load void (...)** %fp, align 8 ; <void (...)*> [#uses=1] >> call void (...)* %0() nounwind >> br label %return >> >> return: ; preds = %entry >> %retval1 = load i32* %retval ; <i32> [#uses=1] >> ret i32 %retval1 >> } >> >> I was wondering why LLVM casts the function pointer to a varargs >> function?Is there some reason why it should do that? >> >> Thanks. >> Arushi >> _______________________________________________ >> LLVM Developers mailing list >> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >> >