Класс смешивания и структура

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

// declare foo (struct) struct foo; // define foo (class) class foo { }; // instance of foo, claiming to be a struct again! Well defined? struct foo bar; // mixing class and struct like this upsets at least one compiler (names are mangled differently) const foo& test() { return bar; } int main() { test(); return 0; } 

Если это неопределенное поведение, кто-то может указать мне в сторону авторитетной (то есть главы и стиха из ISO) ссылки?

Компилятор с проблемами, связанными с этим ( Carbide 2.7 ), является относительно старым, и все другие компиляторы, с которыми я его пробовал, совершенно довольны этим, но, очевидно, это ничего не доказывает.

Моя интуиция заключалась в том, что это должно быть неопределенным поведением, но я не могу найти ничего, чтобы подтвердить это, и я удивлен, что ни одна из версий GCC или Комо так не была предупреждена об этом.

Мне кажется, что это определенное поведение. В частности, в § 9.1 / 2 говорится:

Объявление, состоящее только из class-key identifier ; является либо переоформлением имени в текущей области действия, либо прямым объявлением идентификатора в качестве имени classа. Он вводит имя classа в текущую область.

Стандарт различает использование class , struct или union при определении classа, но здесь, говоря об объявлении, такого различия не делается – использование одного class-key эквивалентно любому другому.

Из предупреждения C4099: имя типа, впервые увиденное с использованием «classа», которое теперь видно с помощью «struct» (MS VS 2k8), похоже, что по крайней мере некоторые компиляторы калечат по-разному в зависимости от используемого ключевого слова, поэтому лучше не полагаться на него, даже если это технически разрешено ( из которых я не могу найти подтверждающую ссылку).

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

«Теоретически нет разницы между теорией и практикой. В теории есть».

В C ++ структура – это class. В частности:

Структура – это class, определенный с помощью структуры classа. (ISO / IEC FDIS 14882: 1998 (E) 9-4)

Это означает, что ваш class, который не был определен со struct , определенно не является структурой. Следовательно, ваше объявление forward с ключом struct class является ошибочным. Я не знаю какой-либо части спецификации, которая позволяет прямому объявлению использовать ключ classа, который явно ошибочен. Я уверен, что рассматриваемые компиляторы с ленивым отношением одинаково относятся к структурам и classам и замалчивают неправильное объявление. Ошибка может не потребоваться от компилятора в этом сценарии, но не должна быть неожиданной.

Я не знаю, является ли это неопределенным (или любой другой категорией не строгого соответствия) по стандарту C, но я знаю, что если у вас есть две единицы перевода, которые не согласны с тем, foo ‘объявляется как «class» или «структура», например:

TU 1

 struct foo; void f(foo&) { ... } 

TU 2

 class foo { ... }; void f(foo&); void g() { foo x; f(x); } 

то, по крайней мере, некоторые компиляторы (в частности, MSVC ++) будут калечить имя f разному в каждой единицы перевода, поэтому определение f в TU 1 не удовлетворяет ссылке на f в TU 2 и вы получите ошибку ссылки. Это происходит в реальной жизни, когда у вас есть заголовок Ah который определяет class A и ему нужно обращаться к classам B , C и D но их достаточно простое декларирование (поэтому он вполне разумно не включает Bh т. Д.) – вам лучше использовать одно и то же ключевое слово для тех форвардных деклараций, которые делают фактические определения!

MSVC10 выдает предупреждение, а на странице предупреждения указано, что тип, указанный в определении, будет использоваться.

http://msdn.microsoft.com/en-us/library/695x5bes.aspx

  • Каковы все общие неопределенные типы поведения, о которых должен знать программист на C ++?
  • Почему это неопределенное поведение для удаления массива производных объектов с помощью базового указателя?
  • Является ли чтение неопределенного значения неопределенным поведением?
  • Когда вызов функции-члена в экземпляре null приводит к неопределенному поведению?
  • В какой момент разыменование нулевого указателя становится неопределенным поведением?
  • Почему этот цикл создает «предупреждение: итерация 3u вызывает неопределенное поведение» и выводит более 4 строк?
  • Рядом постоянное время вращается, что не нарушает стандарты
  • Действительно ли «Неопределенное поведение» действительно позволяет * что-либо * произойти?
  • Как объяснить результат выражения (++ x) + (++ x) + (++ x)?
  • Изменился ли стандарт C ++ в отношении использования неопределенных значений и неопределенного поведения в C ++ 14?
  • Доступ к массиву доступа за пределами C и C ++
  • Interesting Posts

    Как диагностировать медленную загрузку или вход в систему Windows?

    Какие внутренние команды cmd.exe очищают ERRORLEVEL до 0 при успешном завершении?

    Как увеличить размер кучи java в netbeans?

    Почему Eclipse автоматически добавляет поддержку библиотеки appcompat v7 всякий раз, когда я создаю новый проект?

    Ошибка Android – вызвана: java.lang.NoClassDefFoundError: android.support.v4.util.SparseArrayCompat

    Макросы препроцессора с несколькими линиями

    ASP.NET MVC 4 Application Calling Remote WebAPI

    Как предоставить разрешение MODIFY_PHONE_STATE для приложений на Gingerbread

    Robocopy – копирование каталога в другой каталог

    Название центра панели инструментов Android и собственный шрифт

    Где хороший адресный парсер

    Как запустить Metro-приложение из командной строки в Windows 8?

    Custom Vim Highlighting (работает только с определенными типами файлов)

    Обновление конфликта конфликтов для игровых сервисов 9.4.0 Android studio 2.2

    Lost Mac DVD, как я могу получить новую копию диска?

    Давайте будем гением компьютера.