Предупреждение C4099: имя типа, впервые увиденное с использованием 'class', теперь видимое с использованием 'struct' (MS VS 2k8) - PullRequest
15 голосов
/ 22 января 2009

Это предупреждение может беспокоить? Я читал, что это может вызвать ошибочное поведение?

Это пример, который я пытаюсь скомпилировать. Может ли кто-нибудь объяснить мне, почему автор объявляет объект как класс, а затем вводит определение type для структуры? Разве это нормально, если класс POD ?

Спасибо.

Ответы [ 7 ]

25 голосов
/ 22 января 2009

Это предупреждение появляется, когда у вас есть одно объявление типа, которое противоречит другому (один говорит «класс», другой говорит «структура»). Учитывая одно правило определения, все объявления, кроме не более одного, должны быть предварительными объявлениями. Как правило, в предупреждении указывается, что предварительное объявление типа является неправильным и, как правило, является простой опечаткой и должно быть исправлено. В этом случае не должно быть никаких побочных эффектов, но вы действительно должны это исправить.

Могут, однако, произойти некоторые очень неприятные вещи, если у вас есть конфликты имен типов (возможно, вызванные использованием выражений «using пространство имен» или глобальное загрязнение пространства имен). Эти предупреждения могут указывать на то, что вы смешиваете заголовки из двух разных библиотек, а имена типов конфликтуют. Код, скомпилированный в этих условиях, может сделать очень неожиданные вещи.

Мой совет - поймите, почему появилось предупреждение, и исправьте его. Если предупреждение относится к сторонним продуктам, настаивайте на том, чтобы они его исправили.

5 голосов
/ 22 января 2009

Просто чтобы вывести комментарий MSalters против этого поста выше на верхний уровень. У меня было несколько трудно найти ошибки компоновщика в результате того, что VC использовал ключевое слово «class» или «struct» в его искажении имен.

Если вы не ожидаете, что это станет проблемой, вас могут часами чесать голову!

3 голосов
/ 23 июня 2010

Я подробно обсуждаю это предупреждение в своем блоге " Является ли C4099 действительно глупым предупреждением?" . Мой вывод таков, что лучше выключить. :-) Ну хотя бы для меня.

2 голосов
/ 29 апреля 2009

Ричард Корден прав - есть причина, по которой MS предупреждает об этом. Для компилятора MS, декорированные (искаженные) имена включают ключ-класс (struct или class), используемый для объявления типа. Если функция, которая принимает некоторый объект в качестве аргумента или возвращает этот объект, ссылается где-то, когда виден неправильный ключ класса, вы не получите ошибку компилятора, но компоновщик будет жаловаться, потому что оформленные имена различаются. Ошибка компоновщика показывает только символ, который он ищет, и здесь легко пропустить несоответствие ключа класса, поэтому более раннее, более подробное предупреждение компилятора является ценным. Конечно, возможно, что две версии не появятся в одном и том же модуле компиляции, и вы, возможно, некоторое время будете чесать голову, если считаете, что единственное отличие - это видимость элемента по умолчанию.

Разница в искажениях конфликтует со стандартом C ++, который гласит, что предварительные объявления, такие как struct Foo; и class Foo;, эквивалентны, и поэтому должны использовать то же искажение.

1 голос
/ 25 июня 2014

Одна вещь, которую я видел, которая может вызвать это предупреждение, это попытка # импортировать файл .tlb из DLL, в то же время имея ту же DLL в качестве ссылки в вашем проекте. Я только что исправил проблему, удалив DLL как ссылку из моего проекта.

1 голос
/ 22 января 2009

Хотя это считается плохой практикой, я думаю, что не должно быть проблем при смешивании определения класса и объявления структуры, поскольку они в основном имеют один и тот же тип данных. Основное отличие состоит в том, что члены структуры по умолчанию являются открытыми, в отличие от членов класса, которые являются закрытыми, но в остальном структура памяти идентична.

0 голосов
/ 22 января 2009

В c ++ только разница между классом и структурой заключается в том, что переменные-члены класса, функции-члены и базовые классы по умолчанию являются закрытыми, тогда как в структуре они по умолчанию являются открытыми; поэтому тот факт, что класс является POD, не должен иметь здесь никакого значения.
Я полагаю, что это предупреждение исходит от обслуживания кода (определение обновляется где-то, но не где-то еще), и исправляю код так, чтобы предупреждение исчезало (например, с использованием класса в typedef).

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