Вот что у меня есть:
- Debian Trixie с GCC 14.2.0 и CMake 3.31.6
- Тестовый проект с двумя файлами .cpp и одним файлом .h, который сборки.
- Тестовый проект и статическая библиотека с тем же кодом, который не собирается без предупреждений компилятора/компоновщика.
Проверка: sizeof(size_t) = 8, как и ожидалось для длинной беззнаковой базы type.
И в форматах, используемых printf, значение size_t кодируется как %llu.
Когда значение поступает из «локального» кода, это нормально.
Но когда значение поступает из кода статической библиотеки и генерируется сообщение об ошибке, что базовый тип долго без знака и его следует закодировать как %lu
Когда я меняю кодировку на %zu, предупреждения нет, но я предполагаю, что это не так действительно решение проблемы.
Хотя компилятор жалуется во время сборки версии со статической библиотекой, результат работает без проблем.
Мне неясно, каков статус сообщения компилятора. Действительно ли след size_t отличается или это какой-то странный артефакт от использования статических библиотек?
Мне нужно понять, что происходит, просто чтобы не запутаться в будущих проблемах (которые могут иметь или не иметь никакого отношения к этому поведению).
Я искал, но не нашел ничего, объясняющего то, что я вижу.
Если здесь есть какие-либо вопросы, связанные с этим, то я их не узнал.
Я провел некоторое тестирование, чтобы получить минимальный пример для воссоздания поведения «in vitro».
Тесты 4 и 5 имеют один и тот же код, другую модель сборки и демонстрируют различное поведение во время компиляции/компонования. (Весь исходный код и результаты тестов см. ниже.)
- три исходных файла
test#.cpp с main(...) с использованием printf(...) - test#list.h с простым классом.
- test#list.cpp с некоторым поведением класса в нем с использованием printf(...)
Когда три файла собираются в один исполняемый файл, он компилируется без каких-либо проблем.
Когда test#list.cpp встроен в статическую библиотеку и связан с исполняемым файлом, возникают проблемы.
Параметры компилятора — это не то, что я использую для каждого проекта; -Wall;-Wshadow;-Wunused;-Wfatal-errors;-fno-diagnostics-show-caret.
Я подозреваю, что я забыл некоторые параметры компилятора при создании статической библиотеки, но не знаю, какие именно.
Вот исходные файлы, начиная с CMakeLists.txt, а затем шесть исходных файлов (два набора по три файла). Тестирование проводится с использованием cmake 3.31.6, установка Debian Trixie по умолчанию. Я провел те же тесты с MSVC, где не возникло ни одной проблемы, я использую cmake 4.2.1. (Я знаю, не совсем удачное сравнение.)
cmake_minimum_required ( VERSION 3.31.6...4.2.1 )
project( "TestSizeT" LANGUAGES CXX)
set(BUILD_SHARED_LIBS OFF)
add_library(compiler_flags INTERFACE)
set(gcc_like_cxx "$")
set(msvc_cxx "$")
target_compile_options(
compiler_flags INTERFACE
"$"
"$"
)
add_executable(Test4 test4.cpp test4list.cpp)
target_link_libraries(Test4 INTERFACE compiler_flags)
add_library(libTest5 STATIC test5list.cpp)
set_target_properties(libTest5 PROPERTIES LINKER_LANGUAGE CXX POSITION_INDEPENDENT_CODE ON)
target_link_libraries(libTest5 INTERFACE compiler_flags)
add_executable(Test5 test5.cpp)
target_link_libraries(Test5 INTERFACE compiler_flags)
target_link_libraries(Test5 PUBLIC libTest5)
test4.cpp (за исключением строки 1, идентичной test5.cpp)
#include "test4list.h"
#include
#include
int main()
{
list a{};
a.add(sizeof(std::size_t));
a.dump();
fprintf(stdout, "sizeof(size_t) = (size_t)%zu\n", sizeof(std::size_t));
fprintf(stdout, "sizeof(size_t) = (long long unsigned)%llu\n", sizeof(std::size_t));
}
test5.cpp (за исключением строки 1, идентичной test4.cpp)
#include "test5list.h"
#include
#include
int main()
{
list a{};
a.add(sizeof(std::size_t));
a.dump();
fprintf(stdout, "sizeof(size_t) = (size_t)%zu\n", sizeof(std::size_t));
fprintf(stdout, "sizeof(size_t) = (long long unsigned)%llu\n", sizeof(std::size_t));
}
test4list.h и test5list.h (идентичные файлы)
#pragma once
#include
class list : public std::vector {
public:
void add(int);
void dump();
};
test4list.cpp (за исключением строки 1, идентичной test5list.cpp)
#include "test4list.h"
#include
void list::add(int value) { push_back(value); }
void list::dump() {
fprintf(stdout, "list: sizeof(size_t) = (size_t)%zu\n", sizeof(std::size_t));
fprintf(stdout, "list: sizeof(size_t) = (long long unsigned)%llu\n", sizeof(std::size_t));
for (size_t i = 0; i < size(); i++) {
fprintf(stdout, "list[(size_t)%zu] = %d\n", i, at(i));
fprintf(stdout, "list[(long long unsigned)%llu] = %d\n", i, at(i));
}
}
test5list.cpp (за исключением строки 1, идентичной test4list.cpp)
#include "test5list.h"
#include
void list::add(int value) { push_back(value); }
void list::dump() {
fprintf(stdout, "list: sizeof(size_t) = (size_t)%zu\n", sizeof(std::size_t));
fprintf(stdout, "list: sizeof(size_t) = (long long unsigned)%llu\n", sizeof(std::size_t));
for (size_t i = 0; i < size(); i++) {
fprintf(stdout, "list[(size_t)%zu] = %d\n", i, at(i));
fprintf(stdout, "list[(long long unsigned)%llu] = %d\n", i, at(i));
}
}
Фаза генератора CMake не является проблемой, и сборка cmake завершается с ошибкой. Вот подробности.
andre@debian:~/development/_test/SizeT$ cmake -S . -B ./build --fresh
-- The CXX compiler identification is GNU 14.2.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done (0.6s)
-- Generating done (0.0s)
-- Build files have been written to: /home/andre/development/_test/SizeT/build
andre@debian:~/development/_test/SizeT$ cmake --build ./build --clean-first
[ 14%] Building CXX object CMakeFiles/Test4.dir/test4.cpp.o
[ 28%] Building CXX object CMakeFiles/Test4.dir/test4list.cpp.o
[ 42%] Linking CXX executable Test4
[ 42%] Built target Test4
[ 57%] Building CXX object CMakeFiles/libTest5.dir/test5list.cpp.o
[ 71%] Linking CXX static library liblibTest5.a
[ 71%] Built target libTest5
[ 85%] Building CXX object CMakeFiles/Test5.dir/test5.cpp.o
/home/andre/development/_test/SizeT/test5.cpp: In function ‘int main()’:
/home/andre/development/_test/SizeT/test5.cpp:10:62: warning: format ‘%llu’ expects argument of type ‘long long unsigned int’, but argument 3 has type ‘long unsigned int’ [-Wformat=]
[100%] Linking CXX executable Test5
[100%] Built target Test5
andre@debian:~/development/_test/SizeT$
Оба теста выполняются без ошибок.
andre@debian:~/development/_test/SizeT$ ./build/Test4 ; echo $?
list: sizeof(size_t) = (size_t)8
list: sizeof(size_t) = (long long unsigned)8
list[(size_t)0] = 8
list[(long long unsigned)0] = 8
sizeof(size_t) = (size_t)8
sizeof(size_t) = (long long unsigned)8
0
andre@debian:~/development/_test/SizeT$ ./build/Test5 ; echo $?
list: sizeof(size_t) = (size_t)8
list: sizeof(size_t) = (long long unsigned)8
list[(size_t)0] = 8
list[(long long unsigned)0] = 8
sizeof(size_t) = (size_t)8
sizeof(size_t) = (long long unsigned)8
0
andre@debian:~/development/_test/SizeT$
Подробнее здесь: https://stackoverflow.com/questions/798 ... -footprint
Мобильная версия