Инициализируйте большой массив i8, используя небольшую строку в LLVM IR

Я хочу инициализировать большой массив i8 в LLVM IR с небольшой строкой. Я хотел бы сделать что-то вроде этого:

@str = [1024 x i8] c"Hello World!\0A\00"

Обратите внимание, что длина строки составляет всего 14 (или 13, если вы не учитываете нулевой байт) . Мне все равно, что помещается в оставшиеся байты на данный момент. Приведенный выше код не работает из-за constant expression type mismatch поскольку размер массива инициализатора не совпадает с размером массива назначения. Одним из решений будет испускание правильного количества \00После строки, но я не хочу этого делать, так как это приведет к большому количеству ненужного мусора. Есть ли ярлык, который я могу использовать, или мне придется выполнить двухэтапный процесс выделения пространства для строки и затем скопировать в нее строковую константу? Если мне нужно выполнить такую ​​копию, что я должен использовать?

1 ответ

Решение

В LLVM IR определение глобальной переменной должно быть инициализировано. Для инициализации массива константа массива должна соответствовать размеру массива. Таким образом, я не вижу способа инициализировать массив за один шаг без конечных нулей.

Вы можете, однако, использовать zeroinitializer инициализировать массив I8 с нулями, а затем использовать strncpy или же memcpy скопировать небольшую строку к нему. Вы можете написать такой фрагмент на C и посмотреть, как его компилирует clang:

#include <string.h>

extern char str[1024] = "";

int main() {
    char* hello = "Hello World!";
    strncpy(str, hello, sizeof(str));
    return 0;
}

Когда используешь clang -O3 -S -emit-llvm test2.c -o test.ll файл битового кода должен выглядеть примерно так:

@str = global [1024 x i8] zeroinitializer, align 16
@.str = private unnamed_addr constant [13 x i8] c"Hello World!\00", align 1

define i32 @main() nounwind uwtable {
  %1 = tail call i8* @strncpy(i8* getelementptr inbounds ([1024 x i8]* @str, i64 0, i64 0), i8* getelementptr inbounds ([13 x i8]* @.str, i64 0, i64 0), i64 1024) nounwind
  ret i32 0
}

declare i8* @strncpy(i8*, i8* nocapture, i64) nounwind
Другие вопросы по тегам