(495) 925-0049, ITShop интернет-магазин 229-0436, Учебный Центр 925-0049
  Главная страница Карта сайта Контакты
Поиск
Вход
Регистрация
Рассылки сайта
 
 
 
 
 

Уж такой элементарный C/С++: может->является

Источник: habrahabr
habrahabr

Вопрос на пять: что напечатает эта простая программа:

    #include <stdio.h>

    typedef int a;
    a b = 5;

    int main()
    {
       a(b);
       printf("%d\n", b);
       return 0;
    }
Уже натерпевшиеся от своего любимого языка, но ещё не прошерстившие всех бизонов gcc, почувствуют подвох - и правильно. Подсказка номер ноль: это скушает С++, но и простой С не подавится.

Подсказка один. Вот что она напечатает:
Ось  Компиляторы  Результат 
ArchLinux 64 clang 2.9, gcc 4.5.2 0 
Win7 32 Visual С++ 2005, 2008, 2010 1 
но только теперь вопрос другой: а что такое a(b)? Ведь я ключиками повертел: и С++, и С - всё одно. Точнее: clang и gcc печатают одно (0), а вижуальники другое (1).

Здесь уже должно допереть. Нет? Подсказка два: уберите шум, и разверните тип:

    int(b);
Подсказка два++. Привидение приведения типа запросто может постоять и слева от равна, но теперь уже и Майкрософт выдаст ноль:
    int(b) = 0;
Люди с заточенными под 45o мозгами, вообще ещё и думать не начинали - запастили код в http://ideone.com или закомпиляли прямо из буфера - знаем же на нюхах про xsel? Результат такой механической работы с включенным -Wall и есть подсказка три:
   [aviaconstructor@arch64 tmp]# xsel / gcc -xc++ -Wall -
   <stdin>: In function "int main()":
   <stdin>:9:25: warning: "b" is used uninitialized in this function
Программуля-то простая, какой уж тут C++11! Но если вы начали сразу с книжек Александреску и чураетесь святой простоты С, восполняю пробел. Точнее, ставлю один единственный пробел между типом и скобкой. Для самых недогадливых, подсказка четыре (пять, если по счёту):
    int (b);
В этом месте нашего повествования пню ясно, что a(b) или int(b) - это объявление локальной переменной, то же, что и int b. Она-то и закрывает своей грудью глобальную переменную с таким же именем. Уже в комментах к этому посту мы можем посудачить и подебачить на тему:
  • Почему значение стековой (auto) переменной как правило будет детерминировано даже на системах без обнуления свободной памяти?
  • Может ли какая-нибудь правильная реализация на системах с обнулением памяти при каждом запуске выдавать разные значения?
  • И вообще, что выдают другие компиляторы и среды?
Кстати, подвигайте переменную по стеку, если интересно. Конечно, там не только нули и единицы. А здесь и сейчас мы поедем дальше.

Вообще, если озарило до обидного поздно, то вера в человечество может быть восстановлена благим словом, ибо про С и С++ конструкции сказано, что всё, что может быть определением, определением и является. Ещё раз: a(b) смахивает на приведение типа в С++, но на декларацию переменной оно похоже больше. Вот и разгадка не только задачки, но и заглавия нашего поста: стрелочка там - это матзнак следования.

Всё это было бы нечистой воды курьёзом, когда бы у нас, умных, ползали по коду ну только очень умные баги. Вот классика:

   std::string a("my string");
   std::string b();
Две строки, и одна пуста? Ни-фи-га! Второе - определение беспараметральной функции b, возвращающей строку. Руганётся при использовании, слава Богу! Куда хуже, когда хотели как всегда:
   QMutexLocker lock(&globalLock);
а вышло:
   void MyClass::MyFunc()
   {
      QMutexLocker lock();  // видим?
      ThisFuncShallBeProtectedByGlobalLock();
      ++objectVarCounter;
   }
Даже предупреждения не дождётесь - подумаешь, объявление неиспользуемой функции! И работать будет, вот только без лока (Шишков, прости за сплошные англицизмы). В крайнем примере путали объявление переменной с декларацией функции, а вот совсем другой косяк:
   {
      QMutexLocker(&globalLock); // где переменная?
      ...
Нужно ли объяснять почему такой локер работать будет только на себя? А есть у меня ещё и сказочка: мышка бежала, хвостиком вильнула - бдэмс - и вместо равна натоптала точку с запятой в неположенном месте:
   MyEnum myEnumMask ; MyEnum(i);
Нет, уж этот пример надуман! Кривыми хвостиками и не то выписывали - до сих пор работает! Ну да, ну да. Согласен. Я со всем согласен. Но любимый язык мой - враг мой. Будьте внимательны!

Ссылки по теме


 Распечатать »
 Правила публикации »
  Написать редактору 
 Рекомендовать » Дата публикации: 08.02.2012 
 

Магазин программного обеспечения   WWW.ITSHOP.RU
Microsoft Office 365 Персональный 32-bit/x64. 1 ПК/MAC + 1 Планшет + 1 Телефон. Все языки. Подписка на 1 год.
Microsoft Office 365 Бизнес. Подписка на 1 рабочее место на 1 год
Microsoft 365 Business Basic (corporate)
Microsoft Windows Professional 10, Электронный ключ
Microsoft 365 Apps for business (corporate)
 
Другие предложения...
 
Курсы обучения   WWW.ITSHOP.RU
 
Другие предложения...
 
Магазин сертификационных экзаменов   WWW.ITSHOP.RU
 
Другие предложения...
 
3D Принтеры | 3D Печать   WWW.ITSHOP.RU
 
Другие предложения...
 
Новости по теме
 
Рассылки Subscribe.ru
Информационные технологии: CASE, RAD, ERP, OLAP
Безопасность компьютерных сетей и защита информации
Новости ITShop.ru - ПО, книги, документация, курсы обучения
CASE-технологии
Программирование на Microsoft Access
OS Linux для начинающих. Новости + статьи + обзоры + ссылки
Новые материалы
 
Статьи по теме
 
Новинки каталога Download
 
Исходники
 
Документация
 
 



    
rambler's top100 Rambler's Top100