﻿# Чему равно выражение sizeof\(&X\), если X объявлен как "char \*X\[n\];" ?

Рассмотрим пример\.

```cpp
char *(X[64]);
cout << sizeof(&X) << endl;
```

Вопрос, какое значение распечатает эта программа? Правильный ответ "размер указателя"\. В частности это может быть значение 4 в Win32 программе, или 8 в Win64 программе\.

Ответ выше кажется очевидным, однако есть два нюанса, из\-за которых нередко происходит путаница\. Рассмотрим другой пример:

```cpp
char *(X[64]);
memset(&X, 0, sizeof(&X));
```

Это код некорректен\. Мы обнуляем только часть массива X\. Подобные ошибки возникают по двум причинам\.

## Причина первая

Компилятор VS 2005 содержит ошибку, из\-за которой "sizeof\(&X\)" возвращает размер массива\. В результате, этот код, собранный в VS 2005 корректно очистит весь массив\. Соответственно ряд программистов введены в заблуждение и считают приведенный код верным\. Ошибка компилятора исчезает после установки SP1\.

Кстати, вот интересный тест на эту тему, который я встретил в коде в Google C\+\+ Mocking Framework:

```cpp
class TestForSP1 {
private: // GCC complains if x_ is used by sizeof before defining it.
  static char x_[100];
  // VS 2005 RTM incorrectly reports sizeof(&x) as 100, and that value
  // is used to trigger 'invalid negative array size' error. If you
  // see this error, upgrade to VS 2005 SP1 since Google Mock will not
  // compile in VS 2005 RTM.
  static char 
  Google_Mock_requires_Visual_Studio_2005_SP1_or_later_to_compile_[
      sizeof(&x_) != 100 ? 1 : -1];
};
```



## Причина вторая

Первым аргументом функции является "&X"\. На самом деле здесь взятие адреса не обязательно\. Мы и так работаем с массивом\. То есть две следующие записи приводят к одинаковому корректному результату:

```cpp
memset(&X, 0, sizeof(X));
memset(X, 0, sizeof(X));
```

В связи с этим тоже возникает некоторая путаница, и программистам кажется, что sizeof\(&X\) и sizeof\(X\) также даст одинаковый результат\. Это не так\.