2015-01-08 4 views
1

Я применил следующую конструкцию кода в нашей производственной среде (в значительной степени упрощенной).Странное использование static_cast

#include <iostream> 

typedef struct 
{ 
    char entry[10]; 
} 
inn_struct; 

typedef struct 
{  
    inn_struct directory; 
} 
out_struct; 


struct test 
{ 
    static const int 
     ENTRY_LENGTH = (sizeof((static_cast<out_struct*>(0))->directory.entry) 
     /sizeof((static_cast<out_struct*>(0))->directory.entry[0])); 
}; 

int main() 
{ 
    test a; 
    std::cout << test::ENTRY_LENGTH; 
} 

Теперь не считая, очевидно, обфусцированный характер его, так как это просто старый C способ определения длины массива ... Я действительно беспокоил static_cast значения 0. ... Является ли этот код приемлемым? Можете ли вы приложить некоторые отрывки из стандарта C++ к вашему ответу, который говорит мне (если), почему этот код в порядке?

ответ

4

Да, этот код вполне приемлем. См. П. 5.3.3/1 (акцент мой).

Оператор sizeof дает количество байтов в представлении объекта своего операнда. Операнд является либо выражением, которое является неоценимым операндом (статья 5), либо номером .

Выражение не оценивается, поэтому нет проблем с тем, что выглядит как разыменование нулевого указателя.

Заметим также, что в C++ 11, вам не нужно прыгать через этот обруч, и может просто непосредственно ссылаться на элемент класса с SizeOf, благодаря § 5/8 (курсив мой):

В некоторых контекстах, отображаются неориентированные операнды (5.2.8, 5.3.3, 5.3.7, 7.1.6.2). Неопределенный операнд не оценивается. Неоценимый операнд считается полным выражением. [Примечание: В неоцененном операнде член статического класса может быть назван (5.1), и присвоение имен объектам или функциям само по себе не требует предоставления определения (3.2). - конец примечание]

и §5.1.1/13:

ID выражение, что обозначает нестатический элемент данных или не статическую функцию-член класса может использоваться только:

  • ..

  • если что ID выражение обозначает нестатический элемент данных, и он появляется в невычисленном контексте [Пример:

struct S { 
     int m; 
    }; 

    int i = sizeof(S::m); // OK 
    int j = sizeof(S::m + 42); // OK 

- конец пример]

+0

Два примечания относительно лучшей формы (X :: entry): 1. Он работает в Clang и GCC, но не работает в Visual C++ 2013. 2. Лучшая цитата для него - это конец [5.1.1], где также есть пример. – bogdan

+0

@bogdan добавил, что этот раздел тоже не читал этого в первый раз. Также форматирование было раздражающим: - / – Barry

Смежные вопросы