簡體   English   中英

為什么 linker 在鏈接共享和 static 時不會抱怨多個定義

[英]Why linker does not complain about multiple definitions when linking against shared and static

我最近在我正在開發的代碼中遇到了 static 初始化失敗的問題。 這讓我意識到我缺乏關於鏈接過程和全局變量初始化的知識,所以我在 cppcon 上發現了這個非常有趣的關於全局變量、鏈接以及將 static 庫嵌入共享和同時鏈接的可能問題(與全局變量定義)。 基本上說的是,當具有以下結構時:

//static.hpp
#pragma once

#include <string>

extern std::string globalString;

//static.cpp
#include "static.hpp"

std::string globalString;

//shared.hpp
#pragma once

#include "static.hpp"
#include <string>

std::string& getGlobalString();

//shared.cpp
#include "shared.hpp"
#include "static.hpp"

std::string& getGlobalString(){
  return globalString;
}

//main.cpp
#include "static.hpp"
#include "shared.hpp"
#include <iostream>

int main(){
    std::cout << "Global variable: " << globalString <<  std::endl;
    std::cout << "Global var acccesed through shared lib: " << getGlobalString() << std::endl;
    return 0;
}

所有編譯:

clang++ -c -std=c++14 -fpic static.cpp
clang++ -c -std=c++14 -fpic shared.cpp
clang++ -c -std=c++14 main.cpp
ar rsc libstatic.a static.o
clang++ -shared -o libshared.so shared.o -L./ -lstatic
clang++ -L./ -Wl,-rpath=./ main.o -lstatic -lshared

由於多次調用同一個 object 的構造函數和析構函數,導致分段錯誤。 這是令人驚訝的,因為我認為每個 object 構造函數都將被調用一次是不變的!

  • 關於多次調用構造函數/析構函數的標准是什么?
  • 如果在這種情況下,我將 static 的全局嵌入到 main.o 和 libshared.so 中,這是否意味着有一個定義的規則被打破了? 為什么 linker 在鏈接 main 時沒有抱怨第二個定義可用?
  • 當在單獨的翻譯單元中至少有兩個全局時,建立構造和銷毀順序的建議方法之一是在第一次使用時進行初始化。 然而,據我所知,這只能確保施工順序。 毀滅令呢? 如何控制?

這是令人驚訝的,因為我認為每個 object 構造函數都將被調用一次是不變的!

在正確構造的二進制文件中,這是正確的。 在具有 ODR 違規的二進制文件中不一定正確。

關於多次調用構造函數/析構函數的標准是什么?

該標准規定,在正確構造的程序中,構造函數/析構函數只被調用一次。 在違反 ODR 的程序中,任何事情都可能發生(未定義的行為)。

如果在這種情況下,我將 static 的全局嵌入到 main.o 和 libshared.so 中,這是否意味着有一個定義的規則被打破了?

是的。

為什么 linker 在鏈接 main 時沒有抱怨第二個定義可用?

就 linker 而言,你的程序沒有問題。 從 linker 的角度來看,在 static 和共享庫中定義一個全局是完美的。 另請參閱此答案

當在單獨的翻譯單元中至少有兩個全局時,建立構造和銷毀順序的建議方法之一是在第一次使用時進行初始化。 然而,據我所知,這只能確保施工順序。

正確的。 這是針對不同問題的解決方案:兩個全局變量 A 和 B 在單獨的翻譯單元中定義。

你沒有那個問題,你有一個完全不同的問題(違反 ODR)。

毀滅令呢? 如何控制?

在正確構造的程序中,破壞順序保證與構造順序相反。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM