Предупреждение C4099:имя типа, впервые увиденное с помощью 'class', теперь видимое с помощью 'struct' (MS VS 2k8)

StackOverflow https://stackoverflow.com/questions/468486

  •  19-08-2019
  •  | 
  •  

Вопрос

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

Это пример, который я пытаюсь скомпилировать, может ли кто-нибудь объяснить мне, почему автор объявляет объект как класс, но затем преобразует его в структуру typedef?Совершенно нормально ли это делать, если класс является СТРУЧОК?

Спасибо.

Это было полезно?

Решение

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

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

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

Другие советы

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

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top