Глобальные переменные с внутренней связью во встроенных функциях - PullRequest
0 голосов
/ 02 ноября 2018

У меня есть val.h файл исходного кода с глобальной переменной с внутренней связью и встроенной функцией, которая возвращает его адрес:

// val.h
#pragma once
static int val;
inline int* get_val()
{
  return &val;
}

Тогда этот заголовок включен в две разные единицы перевода. Если я вызываю &val в обоих этих единицах, я получаю два разных адреса, и это нормально, так как val имеет внутреннюю связь, и у каждого блока перевода есть свой val. Но если я позвоню get_val() в обоих этих единицах, я получу два одинаковых адреса.

Гарантируется ли такое поведение стандартом, всегда ли мы получим одно и то же значение, возвращаемое вызовом get_val() из любой единицы перевода?

А что если компилятор решит выполнить истинное встраивание, то есть просто заменить вызов get_val() на оператор &val в каждой единице перевода. Получим ли мы в этом случае разные адреса для каждой единицы перевода?

Ответы [ 2 ]

0 голосов
/ 02 ноября 2018

При наличии этого вы получите неопределенное поведение, если вы включите этот заголовочный файл в две разные единицы перевода. Это потому, что выражение return &val будет ссылаться на два разных объекта; Таким образом, тело getVal отличается в обеих единицах перевода, но getVal имеет внешнюю связь. Таким образом, вы нарушаете одно определение правила.

Чтобы преодолеть это, вы также должны определить внутреннюю связь для getVal, т.е. написать static int* get_val() { .... Ключевое слово inline само по себе не будет определять внешнюю или внутреннюю связь.

0 голосов
/ 02 ноября 2018

Ваша функция нарушает правило One Definition , поскольку выражение val относится к разным объектам в разных единицах перевода.

Его поведение не определено.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...