Today I was experimenting on how I could call printf and implement basic c-style null terminated strings.
The first problem I ran in to is how to initialize the string type (an array of i8). I tried using an empty string which gave me an error about the types being wrong and then tried using null, which passes verification but then I get an error when building with llvm-as. I found that odd because LLVMWriteBitcodeToFile DID work so I’m curious if the versions are different or something (should both be LLVM 16). So what really is the correct way to do this in LLVM 16?
Secondly, if I used LLVMWriteBitcodeToFile and built the program printf did work but there was an extra “0” at the end of the string. I’m curious about this because the null terminator \00 was added via the LLVM constant string function. Do I need to use a GEP to get the first index or can I simply pass the pointer like below? Maybe it was because the null initializer too for all I know,
Thanks guys.
@s = global [255 x i8] null
@i = global i32 0
@"$result" = global i8 0
declare i32 @printf(ptr %0, ...)
define i8 @main() {
entry:
store [9 x i8] c"hello %d\00", ptr @s, align 1
store i32 100, ptr @i, align 4
%i = load i32, ptr @i, align 4
%0 = call i32 (ptr, ...) @printf(ptr @s, i32 %i)
%1 = load i8, ptr @"$result", align 1
ret i8 %1
}
Compiling the IR:
llvm-as main.ll -o main.bc
llvm-as: main.ll:4:24: error: null must be a pointer type
@s = global [255 x i8] null
^