Telegram Group & Telegram Channel
#compiler

Прикладные linkage types в C++ 🔗

Стандартное добавление функции в C++ происходит так: в .h-файле пишется объявление функции (которое попадает в много translation unit), а в одном .cpp-файле пишется определение функции.

Чтобы определить функцию в .h-файле, чаще всего пишут спецификатор inline (это рекомендуемый путь), в несколько раз реже static.

Посмотрим, каким будет LLVM IR (компиляторное промежуточное представление C++-кода) для int sum1(), static int sum2(), inline int sum3(): ссылка на godbolt.

У LLVM IR есть интересный список linkage types для символов, типов много. Linkage type определяет, как ведет себя символ во время линковки в бинарник. (Символ - это функция или глобальная переменная)

▪️ У sum1 дефолтный linkage type external - возможно ровно 1 определение символа. Линковщик выдаст ошибку, если в программе будет 0 или >1 определения.

▪️ У sum2 linkage type internal - символ доступен только из того translation unit, где определен. Если в процессе линковки попадется одноименный символ, то линковщик просто переименует sum2, чтобы не было коллизии.

▪️ У sum3 linkage type linkonce_odr. Это типичный weak symbol, как и некоторые другие типы (linkonce, weak).
В программе может быть несколько weak-определений одного и того же символа.
Если все определения символа являются weak, то линковщик берет рандомное определение.
Если какое-то из определений символа является strong (как у sum1), то линковщик берет strong-определение.

В чем отличие linkonce от linkonce_odr?
▪️ В общем случае weak-определения могут быть разными, поэтому компилятор не имеет права заинлайнить вызов weak-функции (после линковки у функции может оказаться совсем другое определение)
▪️ Но Стандарт С++ требует от программиста обеспечить, чтобы inline-функции имели идентичное определение (это естественным образом достигается, если определение находится в .h-файле)
▪️ Поэтому компилятор имеет право заинлайнить вызов метода sum3 - программа от этого сломаться не сможет

Скомпилируем объектный файл
> clang++ -c link.cpp
На Linux получим объектный файл формата ELF. Используем утилиту readelf для чтения таблицы символов. Чтобы вывести исходные имена методов (не mangled-имена), используем утилиту c++filt:
> readelf -s link.o | c++filt

Получим такой вывод (опустил другие символы):
Symbol table '.symtab' contains 21 entries:
Num: Value Size Type Bind Vis Ndx Name
6: 00000000000000c0 18 FUNC LOCAL DEFAULT 2 sum2(int, int)
14: 0000000000000000 18 FUNC GLOBAL DEFAULT 2 sum1(int, int)
20: 0000000000000000 18 FUNC WEAK DEFAULT 7 sum3(int, int)

В общем случае выгоднее использовать inline-методы, чем static-методы! Потому что так меньше загрязняется бинарник, и все статические переменные внутри функции живут в количестве 1 штуки, а не в N штук:
inline int* get_address() {
// `dummy` займет sizeof(int) памяти, а со static-методом было бы N*sizeof(int)
static int dummy;
// inline-метод - возвращает один и тот же указатель
// static-метод - уникальный для каждого translation unit
return &dummy;
}



group-telegram.com/cxx95/38
Create:
Last Update:

#compiler

Прикладные linkage types в C++ 🔗

Стандартное добавление функции в C++ происходит так: в .h-файле пишется объявление функции (которое попадает в много translation unit), а в одном .cpp-файле пишется определение функции.

Чтобы определить функцию в .h-файле, чаще всего пишут спецификатор inline (это рекомендуемый путь), в несколько раз реже static.

Посмотрим, каким будет LLVM IR (компиляторное промежуточное представление C++-кода) для int sum1(), static int sum2(), inline int sum3(): ссылка на godbolt.

У LLVM IR есть интересный список linkage types для символов, типов много. Linkage type определяет, как ведет себя символ во время линковки в бинарник. (Символ - это функция или глобальная переменная)

▪️ У sum1 дефолтный linkage type external - возможно ровно 1 определение символа. Линковщик выдаст ошибку, если в программе будет 0 или >1 определения.

▪️ У sum2 linkage type internal - символ доступен только из того translation unit, где определен. Если в процессе линковки попадется одноименный символ, то линковщик просто переименует sum2, чтобы не было коллизии.

▪️ У sum3 linkage type linkonce_odr. Это типичный weak symbol, как и некоторые другие типы (linkonce, weak).
В программе может быть несколько weak-определений одного и того же символа.
Если все определения символа являются weak, то линковщик берет рандомное определение.
Если какое-то из определений символа является strong (как у sum1), то линковщик берет strong-определение.

В чем отличие linkonce от linkonce_odr?
▪️ В общем случае weak-определения могут быть разными, поэтому компилятор не имеет права заинлайнить вызов weak-функции (после линковки у функции может оказаться совсем другое определение)
▪️ Но Стандарт С++ требует от программиста обеспечить, чтобы inline-функции имели идентичное определение (это естественным образом достигается, если определение находится в .h-файле)
▪️ Поэтому компилятор имеет право заинлайнить вызов метода sum3 - программа от этого сломаться не сможет

Скомпилируем объектный файл

> clang++ -c link.cpp
На Linux получим объектный файл формата ELF. Используем утилиту readelf для чтения таблицы символов. Чтобы вывести исходные имена методов (не mangled-имена), используем утилиту c++filt:
> readelf -s link.o | c++filt

Получим такой вывод (опустил другие символы):
Symbol table '.symtab' contains 21 entries:
Num: Value Size Type Bind Vis Ndx Name
6: 00000000000000c0 18 FUNC LOCAL DEFAULT 2 sum2(int, int)
14: 0000000000000000 18 FUNC GLOBAL DEFAULT 2 sum1(int, int)
20: 0000000000000000 18 FUNC WEAK DEFAULT 7 sum3(int, int)

В общем случае выгоднее использовать inline-методы, чем static-методы! Потому что так меньше загрязняется бинарник, и все статические переменные внутри функции живут в количестве 1 штуки, а не в N штук:
inline int* get_address() {
// `dummy` займет sizeof(int) памяти, а со static-методом было бы N*sizeof(int)
static int dummy;
// inline-метод - возвращает один и тот же указатель
// static-метод - уникальный для каждого translation unit
return &dummy;
}

BY C++95


Warning: Undefined variable $i in /var/www/group-telegram/post.php on line 260

Share with your friend now:
group-telegram.com/cxx95/38

View MORE
Open in Telegram


Telegram | DID YOU KNOW?

Date: |

Telegram does offer end-to-end encrypted communications through Secret Chats, but this is not the default setting. Standard conversations use the MTProto method, enabling server-client encryption but with them stored on the server for ease-of-access. This makes using Telegram across multiple devices simple, but also means that the regular Telegram chats you’re having with folks are not as secure as you may believe. Official government accounts have also spread fake fact checks. An official Twitter account for the Russia diplomatic mission in Geneva shared a fake debunking video claiming without evidence that "Western and Ukrainian media are creating thousands of fake news on Russia every day." The video, which has amassed almost 30,000 views, offered a "how-to" spot misinformation. Again, in contrast to Facebook, Google and Twitter, Telegram's founder Pavel Durov runs his company in relative secrecy from Dubai. Telegram Messenger Blocks Navalny Bot During Russian Election "There are several million Russians who can lift their head up from propaganda and try to look for other sources, and I'd say that most look for it on Telegram," he said.
from us


Telegram C++95
FROM American