Question

Static vs Shared Libraries in C/C++: What’s the Difference?

ccppshared-librariesstatic-libraries

Question

What is the difference between static libraries and shared libraries in C/C++?

I am using Eclipse, and I see project types such as Static Library and Shared Library. What does each one mean, and does one have an advantage over the other?

Short Answer

By the end of this page, you will understand what static and shared libraries are, how they are linked into a program, and the practical trade-offs between them. You will also see when each type is commonly used in real C/C++ projects and how to choose the right one for your application.

Concept

A library is a collection of compiled code that other programs can use.

In C and C++, the two main kinds are:

  • Static libraries
  • Shared libraries (also called dynamic libraries)

The main difference is when the library code becomes part of your program.

Static library

A static library is linked into the executable at build time.

  • On Linux, static libraries often use .a
  • On Windows, they often use .lib

When you build your program, the linker copies the needed parts of the static library into the final executable. After that, the executable contains its own copy of that code.

Shared library

A shared library is linked at runtime or prepared for runtime linking.

  • On Linux, shared libraries often use .so
  • On macOS, they often use .dylib
  • On Windows, they are commonly .dll

With a shared library, the executable usually contains a reference to the library instead of a full copy of its code. The operating system loads the shared library when the program starts, or sometimes later on demand.

Why this matters

This affects several important things:

  • Executable size
  • Memory usage
  • Deployment
  • Updates and bug fixes
  • Compatibility

Core idea

  • Static library = code is bundled into your program
  • Shared library = code stays separate and is loaded when needed

Neither is always better. The right choice depends on your project goals.

Mental Model

Think of a library like a set of tools.

  • With a static library, you pack the exact tools you need into your own toolbox before leaving home.
  • With a shared library, you travel lighter and borrow the tools from a shared workshop when you arrive.

That leads to the trade-off:

  • Packing your own tools means you are more independent.
  • Borrowing shared tools means less duplication, but you must be sure the workshop has the right tools available.

In programming terms:

  • Static means bigger self-contained executables
  • Shared means smaller executables but an external dependency at runtime
Take Quiz

Syntax and Examples

Basic idea

In C/C++, you usually:

  1. Write source files
  2. Compile them into object files
  3. Package object files into a library
  4. Link that library into an executable

Example library code

// math_utils.h
#ifndef MATH_UTILS_H
#define MATH_UTILS_H

int add(int a, int b);

#endif
// math_utils.cpp
#include "math_utils.h"

int add(int a, int b) {
    return a + b;
}

Example program using the library

// main.cpp
#include <iostream>
#include "math_utils.h"

int main() {
    std::cout << add(2, 3) << std::endl;
    return 0;
}

Static library flow

The add function is compiled into a static library, and during linking, the needed code is copied into the final executable.

Result:

  • The executable can often run without the .a or .lib file being present later.
  • The executable is usually larger.

Shared library flow

The add function is compiled into a shared library, and the executable links to that external library.

Result:

  • The executable is usually smaller.
  • The shared library file must usually be available when the program runs.

Simplified build commands on Linux

Build a static library

g++ -c math_utils.cpp -o math_utils.o
ar rcs libmathutils.a math_utils.o
g++ main.cpp -L. -lmathutils -o app_static

Build a shared library

g++ -fPIC -c math_utils.cpp -o math_utils.o
g++ -shared -o libmathutils.so math_utils.o
g++ main.cpp -L. -lmathutils -o app_shared

Note

The exact commands vary by platform and build system, but the concept is the same:

  • static: library code is copied into the executable
  • shared: executable depends on an external library file

Step by Step Execution

Consider this code:

// main.cpp
#include <iostream>
#include "math_utils.h"

int main() {
    int result = add(4, 5);
    std::cout << result << std::endl;
    return 0;
}

Suppose add is stored in a library.

If it is a static library

Step 1

The compiler compiles main.cpp into an object file.

Step 2

The linker sees that main calls add.

Step 3

The linker looks inside the static library and finds the compiled add function.

Step 4

The linker copies that machine code into the final executable.

Step 5

When the program runs, add is already inside the executable.

If it is a shared library

Step 1

The compiler compiles main.cpp into an object file.

Step 2

The linker records that add will come from a shared library.

Step 3

The final executable is created without embedding the full library code.

Step 4

When the program starts, the operating system loads the shared library.

Step 5

The call to add is resolved using the loaded shared library.

What changes in practice?

  • Static: more is decided at build time
  • Shared: more is resolved at load time or runtime

That is the key execution difference.

Real World Use Cases

When static libraries are useful

  • Command-line tools distributed as a single file
  • Embedded systems where deployment must be simple
  • Internal utilities that should run without extra installed dependencies
  • Builds that need maximum portability across machines with unknown library setups

Example:

  • A small utility shipped to many servers where you do not want to install extra runtime libraries.

When shared libraries are useful

  • Large applications split into reusable modules
  • System libraries used by many programs
  • Plugins and extension systems
  • Applications that need updates without rebuilding everything

Example:

  • Many programs on Linux use the same shared C standard library instead of each program containing its own private copy.

Why operating systems use shared libraries heavily

Shared libraries reduce duplication:

  • less disk space overall
  • less memory usage when many processes use the same library
  • easier central updates for security fixes
Take Quiz

Real Codebase Usage

In real projects, developers choose based on deployment, reuse, and maintenance needs.

Common static library patterns

  • Bundling utility code used by one final application
  • Vendoring third-party dependencies to simplify deployment
  • Producing self-contained binaries for tools and installers

Example pattern:

  • A project builds several internal static libraries such as core, utils, and parsing, then links them into one executable.

Common shared library patterns

  • Public SDKs distributed for other teams or customers
  • Plugin architectures where modules are loaded separately
  • Reusable platform components used by many executables
  • System-level libraries maintained independently from applications

Practical concerns in real codebases

Versioning

Shared libraries require careful version compatibility. If a function signature changes, older executables may break.

Deployment

Static linking simplifies deployment because the executable is more self-contained. Shared linking requires shipping or installing the correct library versions.

Updates

If ten applications use one shared library, updating that library can fix a bug for all ten applications at once.

Build organization

A common structure is:

  • static libraries for internal implementation pieces
  • shared libraries for APIs intended to be reused by multiple programs

Error handling and startup issues

With shared libraries, programs can fail at startup if the required library file is missing or incompatible. Developers often need packaging, install scripts, or runtime path configuration to avoid this.

Common Mistakes

1. Thinking shared libraries are always better

They are not always better.

Shared libraries help with reuse and smaller executables, but they add runtime dependencies and versioning issues.

2. Thinking static libraries are always independent of everything

A statically linked library may still rely on other runtime components depending on how the program is built.

3. Forgetting runtime availability for shared libraries

A program may compile and link successfully, but fail to run if the shared library cannot be found.

Example problem:

./app_shared
# error while loading shared libraries: libmathutils.so: cannot open shared object file

Avoid this by:

  • installing the library in a standard location
  • setting library search paths correctly
  • packaging the right runtime files

4. Ignoring binary compatibility

Changing a shared library API or ABI carelessly can break existing programs.

For example, changing class layouts or exported function signatures may cause runtime problems.

5. Mixing up build-time and runtime linking

Beginners often assume linking happens only once.

But with shared libraries:

  • part of the decision happens at build time
  • actual loading happens at runtime

6. Assuming smaller executable means smaller total deployment

A shared-library executable may be small, but you still need to ship the .so, .dll, or .dylib file.

Broken expectation example

// Program builds fine, but deployment is incomplete
// The executable depends on a shared library that is not shipped.

The code is not the problem. The packaging is.

Comparisons

Static vs shared libraries

FeatureStatic LibraryShared Library
Linked whenBuild timeLoad time / runtime
File types.a, .lib.so, .dll, .dylib
Executable sizeUsually largerUsually smaller
Runtime dependencyUsually lessUsually more
Updating library separatelyNo, usually rebuild neededYes, often possible
Memory sharing between processesNo separate shared copyOften yes
Deployment simplicityOften simplerOften more complex
Version compatibility issuesUsually fewer at runtimeUsually more important

Which should you choose?

SituationBetter fit
Single self-contained toolStatic library
Many apps using the same codeShared library
Easy deployment to unknown machinesStatic library
Central security updatesShared library
Plugin systemShared library

Shared libraries vs source code reuse

Sometimes instead of creating a reusable library, teams directly include source files in multiple projects. That is usually harder to maintain because:

  • fixes must be copied everywhere
  • builds become inconsistent
  • reuse is less structured

Libraries provide a cleaner reuse boundary.

Take Quiz

Cheat Sheet

Quick reference

  • Static library: linked into the executable at build time
  • Shared library: loaded separately at runtime

Common file extensions

PlatformStaticShared
Linux.a.so
Windows.lib.dll
macOS.a.dylib

Rules of thumb

  • Choose static when you want simpler deployment.
  • Choose shared when multiple programs should reuse one library installation.
  • Choose shared when updating the library independently matters.
  • Choose static when runtime dependency problems would be painful.

Key trade-off

  • Static = larger executable, fewer runtime dependencies
  • Shared = smaller executable, more flexible updates, more deployment/version concerns

Important edge case

A small executable linked to a shared library is not fully standalone. It still needs the shared library at runtime.

Interview-style answer

A static library is copied into the executable during linking. A shared library stays separate and is loaded by the operating system when the program runs. Static linking simplifies deployment, while shared linking improves reuse and can reduce duplication across programs.

FAQ

What is the main difference between static and shared libraries?

A static library becomes part of the executable during build time. A shared library remains separate and is loaded when the program runs.

Are shared libraries faster than static libraries?

Not necessarily in a way that matters for most beginners. The main differences are deployment, memory sharing, and update flexibility, not usually obvious speed gains.

Why would I choose a static library?

Choose a static library when you want a more self-contained executable and easier deployment.

Why would I choose a shared library?

Choose a shared library when many programs use the same code or when you want to update the library without rebuilding every application.

Can a program fail because of a shared library?

Yes. If the required shared library is missing, in the wrong location, or incompatible, the program may fail to start.

Does Eclipse decide which one is better?

No. Eclipse only gives you project types and build options. The better choice depends on your project’s deployment and maintenance needs.

Are static libraries always larger?

Usually the final executable is larger because library code is copied into it. However, the exact size depends on how much code is actually linked.

Can I use both in the same project?

Yes. Real projects often use a mix of static and shared libraries depending on which components are internal, reusable, or distributed separately.

Take Quiz

Mini Project

Description

Build a tiny C++ calculator library and use it from an application in two ways: once as a static library and once as a shared library. This demonstrates the exact difference in how the final executable depends on the library.

Goal

Create a reusable C++ library, link it into an app, and understand how static and shared builds affect the final program.

Requirements

[ "Create a library that exposes at least two functions such as add and multiply.", "Write a small application that calls those library functions.", "Build the library as a static library and link the application against it.", "Build the same library as a shared library and link the application against it.", "Observe the deployment difference between the two executables." ]

Take Quiz

Keep learning

Related questions

View more