Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Двоичный интерфейс приложения (Application binary interface, ABI)

Этот раздел документирует особенности, которые влияют на ABI скомпилированного вывода крейта.

См. внешние функции для информации о указании ABI для экспорта функций. См. внешние блоки для информации о указании ABI для линковки внешних библиотек.

Атрибут used

Атрибут used может быть применен только к static элементам. Этот атрибут принуждает компилятор сохранять переменную в выходном объектном файле (.o, .rlib, и т.д., исключая финальные бинарные файлы) даже если переменная не используется или не ссылается никаким другим элементом в крейте. Однако, линковщик все еще свободен удалить такой элемент.

Ниже приведен пример, который показывает, при каких условиях компилятор сохраняет static элемент в выходном объектном файле.

#![allow(unused)]
fn main() {
// foo.rs

// Это сохраняется из-за `#[used]`:
#[used]
static FOO: u32 = 0;

// Это удаляемо, потому что не используется:
#[allow(dead_code)]
static BAR: u32 = 0;

// Это сохраняется, потому что публично достижимо:
pub static BAZ: u32 = 0;

// Это сохраняется, потому что на него ссылается публичная, достижимая функция:
static QUUX: u32 = 0;

pub fn quux() -> &'static u32 {
    &QUUX
}

// Это удаляемо, потому что на него ссылается приватная, неиспользуемая (мертвая) функция:
static CORGE: u32 = 0;

#[allow(dead_code)]
fn corge() -> &'static u32 {
    &CORGE
}
}
$ rustc -O --emit=obj --crate-type=rlib foo.rs

$ nm -C foo.o
0000000000000000 R foo::BAZ
0000000000000000 r foo::FOO
0000000000000000 R foo::QUUX
0000000000000000 T foo::quux

Атрибут no_mangle

Атрибут no_mangle может быть использован на любом элементе для отключения стандартного искажения имен символов (name mangling). Символ для элемента будет идентификатором имени элемента.

Дополнительно, элемент будет публично экспортирован из произведенной библиотеки или объектного файла, аналогично атрибуту used.

Этот атрибут небезопасен, так как немангированный символ может столкнуться с другим символом с тем же именем (или с хорошо известным символом), приводя к неопределенному поведению.

#![allow(unused)]
fn main() {
#[unsafe(no_mangle)]
extern "C" fn foo() {}
}

2024 Edition differences

До редакции 2024 года разрешалось использовать атрибут no_mangle без квалификации unsafe.

Атрибут link_section определяет секцию объектного файла, в которую будет помещено содержимое функции или статической переменной.

Атрибут link_section использует синтаксис MetaNameValueStr для указания имени секции.

#![allow(unused)]
fn main() {
#[unsafe(no_mangle)]
#[unsafe(link_section = ".example_section")]
pub static VAR1: u32 = 1;
}

Этот атрибут небезопасен, так как позволяет пользователям помещать данные и код в секции памяти, не ожидающие их, такие как изменяемые данные в области только для чтения.

2024 Edition differences

До редакции 2024 года разрешалось использовать атрибут link_section без квалификации unsafe.

Атрибут export_name

Атрибут export_name определяет имя символа, который будет экспортирован для функции или статической переменной.

Атрибут export_name использует синтаксис MetaNameValueStr для указания имени символа.

#![allow(unused)]
fn main() {
#[unsafe(export_name = "exported_symbol_name")]
pub fn name_in_rust() { }
}

Этот атрибут небезопасен, так как символ с пользовательским именем может столкнуться с другим символом с тем же именем (или с хорошо известным символом), приводя к неопределенному поведению.

2024 Edition differences

До редакции 2024 года разрешалось использовать атрибут export_name без квалификации unsafe.