Program Building
Preprocessing, compilation, linking, visibility, linkage, and compile-time evaluation.
31 questions
JuniorTheoryCommonHow does #include work? How do you guard against double inclusion?
How does #include work? How do you guard against double inclusion?
#include directs the preprocessor to copy the named file's content. Guard against double inclusion with classic #ifndef/#define/#endif macros, or with #pragma once. Search order: "" checks the current directory first, <> only system paths.
Common mistakes
- ✗Using an include guard macro that is not unique — two headers with the same guard name silently suppress one
- ✗Placing definitions (not just declarations) in headers without
inline/static/constexpr— ODR violation - ✗Circular includes — A includes B, B includes A. Use forward declarations to break cycles.
Follow-up questions
- →What is the difference between
#include <file>and#include "file"in terms of search order? - →How do C++20 modules replace the include/guard paradigm?
JuniorTheoryCommonDescribe the stages of developing a library or program.
Describe the stages of developing a library or program.
Pipeline: Preprocessing expands macros and headers, Compilation lowers each TU to assembly, Assembly produces a relocatable object, Linking merges objects and resolves symbols. For a library, add packaging as .a/.so/.dll and a consumer target.
Common mistakes
- ✗Confusing compilation with building — compilation is one TU, build is the whole pipeline
- ✗Not separating interface (headers) from implementation — exposes implementation details and increases compile time
- ✗Forgetting that changing a public header of a shared library can break ABI — use PIMPL or versioned symbols
Follow-up questions
- →What is the difference between
.aand.sofiles and when would you choose each? - →What is ABI stability and why does it matter for shared library evolution?
JuniorTheoryCommonHow do macros work? Pitfalls vs inline and constexpr.
How do macros work? Pitfalls vs inline and constexpr.
Macros are textual substitutions with no type safety, scoping or debug info; arguments are evaluated multiple times and they can't be overloaded. inline functions have types and scope; constexpr also runs at compile time. Macros remain useful for include guards and assert.
Common mistakes
- ✗Macro argument evaluated twice:
MAX(++i, j)incrementsitwice if it wins the comparison - ✗Macro without full parenthesisation:
#define ADD(a,b) a+bgives wrong results inADD(1,2)*3(1+2*3=7) - ✗Using a macro for constants instead of
constexpr— macros have no type, cannot be addressed, not visible in debuggers
Follow-up questions
- →When is an X-macro pattern useful and how does it work?
- →How do
if constexpr(C++17) andstatic_assertreplace many uses of#if?
JuniorTheoryCommonWhat is compiler optimisation? Common flags (-O1/-O2/-O3).
What is compiler optimisation? Common flags (-O1/-O2/-O3).
Optimisation transforms code for speed or smaller size without changing observable behaviour. GCC/Clang levels: -O0 none, -O1 basic, -O2 standard production, -O3 aggressive (may bloat binary), -Os for size. Most production builds use -O2 or -O3 -DNDEBUG.
Common mistakes
- ✗Benchmarking in debug build (
-O0) and drawing performance conclusions — results are meaningless for production - ✗Using
-O3without profiling — it can regress performance due to instruction cache pressure from code bloat - ✗Not combining
-O2with-DNDEBUG— release builds should disable assert
Follow-up questions
- →What does
-ffast-mathdo and why can it produce incorrect results for IEEE 754 code? - →How does link-time optimisation (LTO) extend per-TU optimisations?
JuniorTheoryCommonWhat is the difference between preprocessing, compilation, and linking?
What is the difference between preprocessing, compilation, and linking?
Preprocessing expands includes, macros, and conditional branches. Compilation turns each translation unit into an object file and checks C++ semantics. Linking resolves symbols across object files and libraries into an executable or shared library.
Common mistakes
- ✗Expecting the compiler to see definitions from another .cpp file directly
- ✗Putting non-inline function definitions into headers and causing duplicate symbols
- ✗Confusing a compile error with an unresolved external link error
Follow-up questions
- →What is a translation unit?
- →How can you inspect preprocessor output?
JuniorTheoryCommonHow does the preprocessor work? What directives exist?
How does the preprocessor work? What directives exist?
The preprocessor is a textual substitution stage before compilation, handling lines starting with #. Key directives: #include, #define/#undef, #if/#ifdef/#else/#endif, #pragma, #error, #line. It works purely on text — no types, no scopes.
Common mistakes
- ✗Defining macros with no parentheses around arguments:
#define SQ(x) x*xgives wrong result forSQ(1+2)(1+2*1+2=5) - ✗Not guarding headers against double inclusion —
#pragma onceor classic include guards - ✗Misusing conditional compilation to hide platform-specific code across a large codebase — prefer runtime polymorphism or constexpr if
Follow-up questions
- →What is
#pragma onceand how does it differ from traditional include guards? - →What is the
__VA_ARGS__variadic macro and when would you use it?
JuniorDebuggingCommonHow do you debug an 'undefined reference to' linker error?
How do you debug an 'undefined reference to' linker error?
Demangle with c++filt, then check: did you compile the .cpp with the definition, miss extern "C", get link order wrong, or forget the library? nm libfoo.a | grep sym shows whether it's defined; ldd binary shows resolved shared-library dependencies.
Common mistakes
- ✗Putting
-lfoobefore the object that uses it — link order matters - ✗Defining a function in a header and using it from multiple TUs without
inlineor template — multiple definition - ✗Forgetting to link in
pthread,m,dl, etc.
Follow-up questions
- →Why does linker order matter for static libraries but not shared?
- →How do you find which library provides a symbol on Linux?
MiddleDesignCommonA project still uses old directory-scoped CMake commands like include_directories and link_libraries, and dependencies keep leaking into unrelated targets. Explain what target-based (modern) CMake is and why the target_* commands with PUBLIC/PRIVATE/INTERFACE scope are preferred over the older directory-level commands.
A project still uses old directory-scoped CMake commands like include_directories and link_libraries, and dependencies keep leaking into unrelated targets. Explain what target-based (modern) CMake is and why the target_* commands with PUBLIC/PRIVATE/INTERFACE scope are preferred over the older directory-level commands.
Modern CMake (3.0+) treats targets as the primary unit: target_* commands with PUBLIC/PRIVATE/INTERFACE propagate properties to consumers, while old global commands bleed into unrelated targets.
Common mistakes
- ✗Mixing global
include_directoriesand per-target — confusing precedence - ✗Using
PUBLICeverywhere — leaks dependencies to consumers unnecessarily - ✗Forgetting
INTERFACEfor header-only libraries
Follow-up questions
- →What does
INTERFACElibrary mean in CMake? - →How do
find_packageconfig files use exported targets?
MiddleTheoryCommonWhat is the difference between debug and release builds?
What is the difference between debug and release builds?
Debug (-O0 -g) keeps full symbols and assert, easy to step through. Release (-O2 -DNDEBUG) optimises aggressively and drops asserts. RelWithDebInfo (-O2 -g -DNDEBUG) keeps symbols for crash analysis without losing speed.
Common mistakes
- ✗Benchmarking in debug build — meaningless; optimisation can change results by 10-100x
- ✗Shipping production without
-DNDEBUG— assert calls remain and may expose sensitive data in error messages - ✗Not keeping debug symbols for production binaries — crash stack traces are useless without them
Follow-up questions
- →What is a
.pdbfile on Windows and what is its Linux equivalent? - →How does
cmake -DCMAKE_BUILD_TYPE=RelWithDebInfowork under the hood?
MiddleTheoryCommonWhat does extern "C" do and why is it needed?
What does extern "C" do and why is it needed?
extern "C" disables C++ name mangling for the enclosed declarations so symbols match what a C compiler emits. Needed when exporting C++ functions to be called from C or importing C library functions. It has no effect on class or template members.
Common mistakes
- ✗Forgetting
extern "C"when implementing a C-API callback passed to a C library — the symbol is mangled and the library cannot find it - ✗Trying to use
extern "C"with a C++ class or template — only free functions and variables are supported - ✗Not wrapping
extern "C"blocks in#ifdef __cplusplusin shared headers — when included from C,__cplusplusis not defined, so the block would not be needed and the guard avoids the syntax error
Follow-up questions
- →How does name mangling encode the parameter types of a function?
- →What is a C-compatible API design pattern for C++ libraries (opaque handle idiom)?
MiddleTheoryCommonWhat is -fPIC and why is it needed for shared libraries?
What is -fPIC and why is it needed for shared libraries?
-fPIC (Position-Independent Code) makes the compiler emit code without absolute addresses — references go through the GOT or are PC-relative. It's mandatory for shared libraries because they can load at any virtual address (ASLR).
Common mistakes
- ✗Forgetting
-fPICfor objects that go into a.so— linker error:relocation can not be used when making a shared object - ✗Using
-fPICfor static libraries unnecessarily — adds a small overhead (indirect GOT access) that is not needed for static linking - ✗Confusing
-fPIC(large model) with-fpic(small model) —-fpichas a smaller GOT size limit;-fPICis safer
Follow-up questions
- →How does ASLR interact with
-fPICto improve security? - →What is the performance difference between PIC and non-PIC code and when does it matter?
MiddleTheoryCommonWhat is the difference between scope, linkage, and symbol visibility?
What is the difference between scope, linkage, and symbol visibility?
Scope controls where a name is visible in source code. Linkage controls whether declarations in different translation units refer to the same entity. Symbol visibility controls whether a symbol is exported from a shared library or kept internal to the binary.
Common mistakes
- ✗Thinking private/protected controls linker visibility
- ✗Using static for every hidden symbol instead of understanding namespaces and anonymous namespaces
- ✗Exporting too many symbols from a shared library and making ABI harder to maintain
Follow-up questions
- →What is internal linkage?
- →How does default symbol visibility affect shared library ABI?
MiddleTheoryCommonWhat is the One Definition Rule? What error occurs if two files define the same function?
What is the One Definition Rule? What error occurs if two files define the same function?
ODR: every non-inline variable or function has at most one definition in the whole program; inline, templates and constexpr may be defined in many TUs only if every definition is identical. Breaking the first yields a linker error; breaking the second is silent UB.
Common mistakes
- ✗Defining a non-inline function in a header included in multiple TUs — classic ODR violation, linker error
- ✗Providing different definitions of an inline function in different TUs — silently picks one, possible wrong-code bugs
- ✗Not knowing that C++17
inlinevariables solve the ODR problem for global constants in headers
Follow-up questions
- →How do C++20 modules change the ODR rules compared to headers?
- →What is an ODR violation that the linker cannot detect and how do sanitisers help?
MiddleTheoryCommonWhat is the difference between static and dynamic libraries?
What is the difference between static and dynamic libraries?
A static library (.a/.lib) archives objects linked into the executable at link time. A dynamic library (.so/.dll) loads at runtime and is shared across processes, giving smaller binaries, updates without relinking and plugins via dlopen.
Common mistakes
- ✗Forgetting to pass
-fPICwhen compiling objects for a shared library — required for position-independent code - ✗Mixing C++ objects from different compilers or settings in the same shared library — ABI incompatibility
- ✗Not exporting symbols explicitly on Windows — all symbols are hidden by default in
.dll
Follow-up questions
- →What is the PLT/GOT mechanism and why does it add overhead to dynamic library calls?
- →How do you load a shared library at runtime with
dlopen/dlsymon POSIX?
MiddleTheoryCommonWhat build automation systems exist (Make, CMake, Bazel)?
What build automation systems exist (Make, CMake, Bazel)?
Make is rule-based and runs shell commands from a Makefile. CMake is a meta-build system generating Make/Ninja/VS files from CMakeLists.txt and is the C++ open-source standard. Bazel is hermetic and scales to monorepos via strict BUILD declarations.
Common mistakes
- ✗Using
cmake_minimum_requiredwith an outdated version — may silently use deprecated behaviour - ✗Glob-based source file collection (
file(GLOB ...)) — does not auto-update when files are added - ✗Mixing
INTERFACE,PUBLIC, andPRIVATElink properties incorrectly — affects transitive dependency propagation
Follow-up questions
- →What is the difference between
target_include_directoriesPRIVATE and INTERFACE? - →What does
cmake --build . --target installdo and when do you use it?
MiddleTheoryCommonHow do you integrate a third-party library in a C++ project?
How do you integrate a third-party library in a C++ project?
Options: system package via find_package, simplest but unpinned; CMake FetchContent to clone and build from source; git submodule for in-tree control; Conan/vcpkg for binary caching and version resolution; or a manual copy for header-only libraries.
Common mistakes
- ✗Pinning a library version with
FetchContent_Declarebut not locking the hash — updates can silently break the build - ✗Linking against the wrong configuration (Debug vs Release) of a prebuilt library on Windows
- ✗Not reading the library's ABI stability guarantees before updating a minor version
Follow-up questions
- →What is the difference between
find_packageCONFIG mode and MODULE mode in CMake? - →How does vcpkg integrate with CMake via the toolchain file?
SeniorTheoryCommonHow do you work with CMake? Targets, dependencies, install rules.
How do you work with CMake? Targets, dependencies, install rules.
Modern CMake (3.x) is target-based: add_library/add_executable create targets, and target_* commands with PRIVATE/PUBLIC/INTERFACE propagate properties to consumers. install(TARGETS ... EXPORT ...) produces a relocatable package usable via find_package(Foo CONFIG).
Common mistakes
- ✗Using
include_directories/link_libraries(global) instead oftarget_*variants — pollutes all targets - ✗Not setting
CMAKE_INSTALL_PREFIX— installs to/usr/localby default, potentially polluting the system - ✗Forgetting
GNUInstallDirsfor portable install paths — hardcodingliborincludebreaks multilib systems
Follow-up questions
- →What is the difference between
cmake -G "Ninja"andcmake -G "Unix Makefiles"? - →How do you write a
FooConfig.cmakethat a downstream project can consume withfind_package?
MiddlePerformanceOccasionalWhat does ccache do and how does it interact with CI builds?
What does ccache do and how does it interact with CI builds?
ccache is a compiler cache: it hashes preprocessed source plus flags and stores the resulting object, so identical re-compilations skip the compiler. Use CC='ccache gcc' and persist its cache directory between CI runs.
Common mistakes
- ✗Forgetting
CCACHE_BASEDIRin CI — different working directories invalidate the cache - ✗Not persisting the cache directory across CI runs — every build starts cold
- ✗Mixing ccache with sccache without understanding their differences
Follow-up questions
- →How does sccache differ (Mozilla, supports remote)?
- →How do you debug a stale ccache hit?
MiddleTheoryOccasionalHow do you export/import functions from a dynamic library?
How do you export/import functions from a dynamic library?
On Windows, mark exports with __declspec(dllexport) and imports with __declspec(dllimport). On Linux/macOS use -fvisibility=hidden plus __attribute__((visibility("default"))) for an explicit public API. The portable idiom is a macro that expands per OS and per direction.
Common mistakes
- ✗Not using
dllimportin the consumer — the compiler generates an indirect call through a stub instead of a direct PLT call - ✗Exporting C++ class members across DLL boundaries without an ABI compatibility layer — fragile across compiler versions
- ✗Forgetting that on Linux
-fvisibility=hiddenmust be set at compile time, not just at link time
Follow-up questions
- →How do you create an import library (
.lib) from a.dllon Windows? - →What is symbol versioning with
__attribute__((symver))on Linux?
MiddleTheoryOccasionalWhat is DLL hell? How do you avoid it?
What is DLL hell? How do you avoid it?
DLL hell — when multiple apps need different incompatible versions of the same shared library, causing crashes or undefined symbol errors. Mitigations: symbol versioning (SONAME), SxS assemblies on Windows, static linking, containers and strict ABI rules.
Common mistakes
- ✗Changing the order or type of public struct/class members and recompiling only the library — ABI break, crash at runtime
- ✗Exporting non-POD C++ objects across shared library boundaries — mangling and ABI differences make this fragile
- ✗Not bumping the SONAME when making ABI-breaking changes — linker and OS load the wrong version
Follow-up questions
- →How does
rpathhelp control which shared library is loaded at runtime? - →What is
lddand how do you use it to diagnose missing shared library dependencies?
MiddlePerformanceOccasionalWhat is link-time optimization (LTO) and what does it enable?
What is link-time optimization (LTO) and what does it enable?
LTO defers optimisations to link time, when the whole program is visible. Compilers emit IR into object files; the linker re-runs optimisation across TUs, enabling cross-TU inlining and devirtualisation. Enable with -flto (gcc/clang) or /GL+/LTCG (MSVC).
Common mistakes
- ✗Mixing LTO and non-LTO objects from different compiler versions — link error or miscompile
- ✗Enabling LTO without measuring — overhead may eat the gains for small projects
- ✗Forgetting that
-fltomust be on both compile and link steps
Follow-up questions
- →What is ThinLTO and how does it differ from full LTO?
- →How does
-fwhole-programinteract with LTO?
MiddleTheoryOccasionalHow do C++ package managers like Conan and vcpkg work?
How do C++ package managers like Conan and vcpkg work?
Both fetch and build (or download prebuilt) third-party libraries via versioned recipes. Conan uses Python recipes with profiles and lockfiles. vcpkg uses CMake portfiles and vcpkg.json manifests. Both resolve transitive deps.
Common mistakes
- ✗Mixing system, vcpkg, and Conan-installed versions of the same library — link conflicts
- ✗Not pinning versions and breaking builds when a dependency releases a new version
- ✗Using package manager for header-only libraries where a git submodule is simpler
Follow-up questions
- →What is a Conan profile and why do you need separate ones per compiler?
- →How does vcpkg manifest mode differ from classic mode?
MiddlePerformanceOccasionalWhat is a precompiled header (PCH) and when does it speed up builds?
What is a precompiled header (PCH) and when does it speed up builds?
A PCH is a parsed snapshot of a frequently-included header set, saved to disk so subsequent compilations skip re-parsing. CMake enables it via target_precompile_headers. PCH is compiler/version/flag-specific; C++20 modules are the modern replacement.
Common mistakes
- ✗Putting frequently-changing headers in PCH — every change rebuilds everything
- ✗Mixing different compile flags between PCH generation and use
- ✗Adding PCH to a small project where it adds complexity for no gain
Follow-up questions
- →How do C++20 modules replace PCH?
- →What is
ccacheand how does it differ from PCH?
SeniorPerformanceOccasionalThe project compiles slowly. How do you speed it up?
The project compiles slowly. How do you speed it up?
Profile first, then apply ccache for object reuse, Ninja for parallelism, PCH for heavy stable headers, forward declarations to thin includes, unity builds or C++20 modules to cut redundant parsing, and distcc to scale across machines.
Common mistakes
- ✗Adding PCH to every target — PCH invalidation causes full recompile; only stable, widely-included headers benefit
- ✗Using unity builds in development — hides header dependency issues and makes incremental builds useless
- ✗Not profiling the build with
ninja -t graphorcmake --build . --target all -- -j1 2>&1 | grep 'Building'to find the actual bottleneck
Follow-up questions
- →How does Clang's
-ftime-traceidentify which headers cost the most compilation time? - →What is the IWYU (Include What You Use) tool and how does it help?
SeniorTheoryOccasionalWhat are the challenges of cross-platform C++ code?
What are the challenges of cross-platform C++ code?
Cross-platform challenges: OS APIs and paths, compiler/ABI differences, variable type sizes (<cstdint>), endianness, shared library ABI, and build systems (CMake).
Common mistakes
- ✗Hardcoding path separators — use
std::filesystem::pathwhich handles/and\transparently - ✗Using
longfor 64-bit values —longis 32-bit on Windows even in 64-bit mode; useint64_t - ✗Assuming
charis signed — it is implementation-defined; use explicitsigned char/unsigned charorstd::bytefor byte operations
Follow-up questions
- →How do you handle platform-specific code without a sea of
#ifdefs? - →What is the Windows-specific MSVC
/W4equivalent to GCC-Wall -Wextra?
SeniorDesignOccasionalYou are setting up the build for a large, multi-module C++ project that several teams will work on for years. Describe how you would design and structure its build system. Address: reproducibility across machines and CI, keeping rebuilds fast as the codebase grows, expressing inter-module dependencies cleanly, and how sources and targets should be organised. State the properties your design must guarantee — do not prescribe a single tool.
You are setting up the build for a large, multi-module C++ project that several teams will work on for years. Describe how you would design and structure its build system. Address: reproducibility across machines and CI, keeping rebuilds fast as the codebase grows, expressing inter-module dependencies cleanly, and how sources and targets should be organised. State the properties your design must guarantee — do not prescribe a single tool.
Aim for hermetic builds (pinned tools, reproducible), incremental builds via a precise dependency graph, parallel execution, and one CMake target per module with declared PRIVATE/INTERFACE deps. Build out-of-source and list sources explicitly.
Common mistakes
- ✗Putting all source files under a single top-level CMakeLists.txt — becomes unmaintainable; use
add_subdirectory - ✗Not using
target_link_librariestransitively — propagates headers and flags automatically - ✗Not caching compiler output (ccache/sccache) in CI — every clean build recompiles everything from scratch
Follow-up questions
- →What is precompiled headers (PCH) and when does it significantly speed up builds?
- →How does Unity build (amalgamation) trade compile speed for object-file granularity?
SeniorTheoryRareWhat is the ELF file format and what sections does a typical executable contain?
What is the ELF file format and what sections does a typical executable contain?
ELF — binary format on Linux/BSD. Header: architecture, entry point, segment/section tables. Sections: .text (code), .rodata (string literals), .data (init globals), .bss (zero-init, no file space), .symtab/.strtab (symbols), .dynsym/.dynstr (dynamic), .plt/.got (lazy resolution), .debug_* (DWARF).
Common mistakes
- ✗Confusing sections (link view) with segments (load view)
- ✗Putting large initialised arrays in
.datawhen zero-init in.bssis enough - ✗Forgetting that
.bsstakes no file space but does take memory at runtime
Follow-up questions
- →How does the dynamic linker resolve symbols (PLT/GOT lazy binding)?
- →What's the difference between PIE, PIC, and a regular executable?
SeniorPerformanceRareWhat is profile-guided optimization (PGO) and when is it worth the build complexity?
What is profile-guided optimization (PGO) and when is it worth the build complexity?
PGO is a two-stage build: compile with -fprofile-generate, run a representative workload to collect counters, then recompile with -fprofile-use so the compiler lays out hot paths and inlines based on real data. Typical gains 5-20% for perf-critical binaries.
Common mistakes
- ✗Profiling on a non-representative workload — pessimisations on real traffic
- ✗Forgetting to clean profile data when source changes significantly
- ✗Adding PGO before LTO — order matters; both together for best results
Follow-up questions
- →What is AutoFDO and how does it differ from instrumentation-based PGO?
- →How does PGO interact with template-heavy code?
SeniorTheoryRareWhat is the difference between RPATH, RUNPATH, and LD_LIBRARY_PATH?
What is the difference between RPATH, RUNPATH, and LD_LIBRARY_PATH?
All three steer the dynamic linker's library search. RPATH (DT_RPATH) is embedded and consulted before LD_LIBRARY_PATH. RUNPATH (DT_RUNPATH) is embedded but consulted after it. LD_LIBRARY_PATH is the env-var override sitting between them.
Common mistakes
- ✗Hardcoding absolute RPATH and breaking installation moves
- ✗Putting RPATH on a setuid binary — disabled for security
- ✗Confusing RPATH and RUNPATH precedence — flips behaviour with LD_LIBRARY_PATH
Follow-up questions
- →How does
$ORIGINwork in RPATH? - →What does
patchelfdo?
SeniorTheoryRareWhat are static and dynamic code analysers? Examples.
What are static and dynamic code analysers? Examples.
Static analysis inspects code without running it (clang-tidy, cppcheck, compiler warnings, PVS-Studio). Dynamic analysis instruments a running program (AddressSanitizer, UBSan, ThreadSanitizer, Valgrind). Most projects use both.
Common mistakes
- ✗Treating static analysis warnings as optional — false positives are rare in modern tools; treat them as errors in CI
- ✗Running sanitisers only on small unit tests — many bugs only manifest under realistic multi-threaded load
- ✗Combining ASan and TSan — they cannot run simultaneously; separate runs or use separate CI jobs
Follow-up questions
- →How does
clang-tidyintegrate with CMake viaCMAKE_CXX_CLANG_TIDY? - →What is the difference between AddressSanitizer and Valgrind's memcheck in terms of performance overhead?
SeniorTheoryRareWhy and how should shared libraries hide internal symbols by default?
Why and how should shared libraries hide internal symbols by default?
GCC/Clang export every external symbol by default, bloating the symbol table and risking conflicts. Compile with -fvisibility=hidden and mark only public symbols with __attribute__((visibility("default"))). Result: faster dlopen, smaller binaries, better optimisation.
Common mistakes
- ✗Marking entire classes default visibility instead of specific public methods
- ✗Forgetting that template instantiations need explicit visibility on Windows (different mechanism)
- ✗Stripping symbols (
strip) instead of fixing visibility — loses debug info
Follow-up questions
- →How does symbol visibility relate to
dllexport/dllimporton Windows? - →What is
version-scriptand when do you need it?