Функционально-локальная статическая константная переменная Семантика инициализации - PullRequest
2 голосов
/ 19 апреля 2010

Вопросы выделены жирным шрифтом, для тех, кто не может быть обеспокоен прочтением вопроса в глубине.

Это продолжение этого вопроса. Это связано с семантикой инициализации статических переменных в функциях. Статические переменные должны быть инициализированы один раз, а их внутреннее состояние может быть изменено позже - как я ( в настоящее время ) в связанном вопросе. Тем не менее, рассматриваемый код не требует, чтобы функция изменила состояние переменной позже.

Позвольте мне уточнить мою позицию, поскольку мне не требуется изменять внутреннее состояние строкового объекта. Код предназначен для класса признаков для метапрограммирования и, как таковой, выиграл бы от const char * const ptr - таким образом, в идеале необходима статическая переменная const локальной стоимости. Мое обоснованное предположение состоит в том, что в этом случае рассматриваемая строка будет оптимально помещена в память загрузчиком ссылок, и что код является более безопасным и соответствует предполагаемой семантике.

Это приводит к семантике такой переменной "Язык программирования C ++, третье издание - Страуструп", не имеет ничего (что я мог бы найти) сказать по этому вопросу. Все, что сказано, это то, что переменная инициализируется один раз, когда поток управления потоком впервые достигает кода. Это заставляет меня задуматься о целесообразности следующего кода, а если нет, то какова предполагаемая семантика?.

#include <iostream>
const char * const GetString(const char * x_in)
{
    static const char * const x = x_in;
    return x;
}

int main()
{
  const char * const temp = GetString("yahoo");
  std::cout << temp << std::endl;
  const char * const temp2 = GetString("yahoo2");
  std::cout << temp2 << std::endl;
}

Следующий код компилируется в GCC и печатает "Yahoo" дважды. Это то, что я хочу - однако это может не соответствовать стандартам (именно поэтому я публикую этот вопрос). Может быть более элегантно иметь две функции: «SetString» и «String», где последняя переходит к первой. Если он соответствует стандартам, знает ли кто-нибудь о внедрении шаблонов в boost (или где-либо еще)?

редактировать: 11 мая 2010

Я использую следующий макрос для генерации вышеупомянутых методов получения / установки в моих классах, которые кодируют информацию времени компиляции.

#define MACRO_STATIC_SETTING_PTR(name, type)                          \
  static const type const set_##name (const type const name##_in) {   \
    static const type const name = name##_in;                         \
    return name;                                                      \
  }                                                                   \
  static const type const name() {                                    \
    return set_##name(NULL);                                          \
  } 

#define MACRO_STATIC_SETTING(name, type)                              \
  static const type set_##name (const type name##_in) {               \
    static const type name = name##_in;                               \
    return name;                                                      \
  }                                                                   \
  static const type name() {                                          \
    return set_##name(NULL);                                          \
  } 

Эти макросы размещаются внутри объявления класса. Например:

template<class tag>
class ConfigInstance{
public:
  MACRO_STATIC_SETTING_PTR(sqllite3_filename, char *)
};

Надеюсь, это будет полезно для других.

1 Ответ

4 голосов
/ 11 мая 2010

Давайте посмотрим на часть 6.7 §4 (Декларация объявления) стандарта C ++.

Реализации разрешено выполнять раннюю инициализацию других локальные объекты со статической длительностью хранения в одинаковых условиях что реализации разрешено статически инициализировать объект со статической продолжительностью хранения в пространстве имен. В противном случае такой объект инициализируется при первом прохождении контроля через свою декларацию; такой объект считается инициализированным при завершение его инициализации.

Итак, у нас есть два случая:

  1. Либо мы теперь, прежде чем войти в функцию со статическим локальным x, какое значение будет иметь x. Затем компилятору разрешается инициализировать значение как можно раньше (даже во время компиляции).
  2. Теперь значение x не инициализируется только при первом входе в нашу функцию.

Так что да, gcc делает не только то, что вам нужно, это поведение также соответствует стандарту.

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