C++ C++  ·  30 вопросов  ·  ~85 мин  ·  ⏱ Таймер 25:00  ·  Сложный  · 

Сборка, линковка и ABI

Профессиональный тест прослеживает путь от исходного файла до загруженной программы. Задания охватывают единицы трансляции, символы, name mangling, статические и динамические библиотеки, layout типов и изменения, которые компилируются у автора, но ломают двоичных клиентов.

Отвечено: 0 из 30
⏱ --:--
0%
💡 Инструкция: Выберите один ответ из пяти. В тесте 30 вопросов, время — 85 минут. Во многих заданиях недостаточно узнать конструкцию: проследите порядок вычислений, время жизни объектов, владение ресурсами и условия, при которых решение остаётся корректным. После завершения откроются правильные ответы, объяснения, общий результат и тематические шкалы.
Вопрос 1 из 30
Что такое единица трансляции в классической модели?
C++C++20
// report.cpp после препроцессинга фактически содержит
#include "report.hpp"
#include <vector>
#include <string>
int build_report() { /* ... */ }
Вопрос 2 из 30
Что даёт `static` у свободной функции в .cpp?
C++C++20
// file.cpp
namespace {
int parse_impl(std::string_view text) {
    return static_cast<int>(text.size());
}
}

static int checksum(const Buffer& b) {
    return checksum_bytes(b.data(), b.size());
}
Вопрос 3 из 30
Почему объявление без определения может компилироваться, но падать на линковке?
C++C++20
// header
int calculate(int);
// client.cpp
int x = calculate(3);
Вопрос 4 из 30
Почему разные значения макроса перед одним header могут создать ODR-проблему?
C++C++20
// a.cpp
#define MODE 1
#include "config.hpp"
// b.cpp
#define MODE 2
#include "config.hpp"
// config.hpp определяет inline-функцию в зависимости от MODE
Вопрос 5 из 30
Чем определение сущности обычно отличается от её простого объявления?
C++C++20
extern int global_count;          // объявление
int compute(int);                 // объявление

int global_count = 0;             // определение
int compute(int x) { return x; }  // определение
Вопрос 6 из 30
Что делает linker?
C++C++20
g++ -c parser.cpp -o parser.o
g++ -c main.cpp -o main.o
g++ main.o parser.o -o app
# последний шаг разрешает ссылки между объектными файлами
Вопрос 7 из 30
Почему порядок статических библиотек иногда важен у Unix linker?
C++C++20
# app.o использует parse(), определённую в libparser.a
g++ app.o -lparser -lcore -o app
# перестановка архивов может изменить разрешение символов
Вопрос 8 из 30
Что означает duplicate symbol при двух невстроенных определениях одной функции?
C++C++20
// a.cpp
int version() { return 1; }
// b.cpp
int version() { return 2; }
// linker видит два сильных определения version()
Вопрос 9 из 30
Зачем скрывать символы реализации shared library по умолчанию?
C++C++20
# сборка shared library
-fvisibility=hidden

class API_EXPORT Client {
public:
    void send(Request);
};
Вопрос 10 из 30
Почему undefined reference может возникнуть при несовпадении const у метода?
C++C++20
// header
struct X { int value() const; };
// cpp
int X::value() { return 1; }
Вопрос 11 из 30
Зачем C++ компилятор кодирует типы в имени символа?
C++C++20
void process(int);
void process(std::string_view);
namespace net { void process(Packet const&); }
// ABI кодирует различия сигнатур в символах
Вопрос 12 из 30
Что делает `extern "C"` для функции?
C++C++20
extern "C" int plugin_version();
extern "C" void* create_plugin(const HostApi* host);
// C language linkage влияет на связывание имён и типов функций
Вопрос 13 из 30
Можно ли перегрузить две функции с `extern "C"` одним именем?
C++C++20
extern "C" void process(int);
extern "C" void process(double); // две функции с C linkage и одним именем
Вопрос 14 из 30
Для чего нужен demangler?
C++C++20
$ nm libservice.so | grep create
00000000000131a0 T _ZN7service6createENS_6ConfigE
$ c++filt _ZN7service6createENS_6ConfigE
Вопрос 15 из 30
Почему нельзя считать одинаковое mangled name переносимым между MSVC и Itanium ABI?
C++C++20
// одна и та же исходная сигнатура в разных ABI/toolchain
std::string render(const Document&);
// конкретное кодированное имя не является межплатформенным контрактом
Вопрос 16 из 30
Почему добавление private-поля в экспортируемый класс может сломать ABI?
C++C++20
// версия 1 публичного заголовка
class Session { int fd_; };
// версия 2
class Session { int fd_; std::uint64_t trace_id_; };
// клиент выделяет sizeof(Session), известный при своей компиляции
Вопрос 17 из 30
Как pImpl помогает ABI?
Вопрос 18 из 30
Почему нельзя бездумно передавать `std::string` через границу библиотек разных runtime/стандартных библиотек?
C++C++20
// Библиотека A собрана с одной стандартной библиотекой.
extern "C" void consume_name(const std::string& name);

// Приложение B передаёт объект, созданный своим runtime.
std::string name = read_name();
consume_name(name);
Вопрос 19 из 30
Как изменение порядка виртуальных методов может повлиять на ABI?
Вопрос 20 из 30
Почему исключения через C ABI-границу опасны?
Вопрос 21 из 30
Как выяснить, экспортируется ли нужная функция из .so?
Вопрос 22 из 30
Что выявляет ABI comparison tool между двумя версиями библиотеки?
Вопрос 23 из 30
Почему clean build важен при странной ошибке линковки?
Вопрос 24 из 30
Для чего linker map file?
Вопрос 25 из 30
Как обнаружить несовпадающие ABI-флаги вроде `_GLIBCXX_USE_CXX11_ABI`?
C++C++20
// lib.cpp
std::string make_name();

// app.cpp
std::cout << make_name();

// lib и app собраны с разными значениями
// _GLIBCXX_USE_CXX11_ABI.
Вопрос 26 из 30
Что даёт LTO?
Вопрос 27 из 30
Какой риск у unity build?
Вопрос 28 из 30
Почему узкая export visibility может ускорить загрузку shared library?
Вопрос 29 из 30
Какой API наиболее устойчив между компиляторами?
Вопрос 30 из 30
Что измерять при ускорении link step?

Ответьте на все 30 вопросов, чтобы получить результат

🔗 Встроить тест на свой сайт (iframe) ▼

Скопируйте код и вставьте в любое место на вашем сайте:

Также доступна прямая ссылка на embed-страницу