2014-02-11 3 views
2

Я побежал анализатор кода в визуальной студии на большой базе кода и я получил около миллиарда этой ошибки:Pass CString в fprintf

warning C6284: Object passed as parameter '3' when string is required in call to 'fprintf' 

Согласно http://msdn.microsoft.com/en-us/library/ta308ywy.aspx «Этот дефект может производить неправильный вывод или аварии «. Однако мой коллега заявляет, что мы можем просто игнорировать все эти ошибки без каких-либо проблем. Поэтому один из моих вопросов - нам нужно что-то сделать, или мы можем просто оставить его как есть?

Если эти ошибки необходимо решить, что является самым лучшим подходом к его решению?

он будет работать, чтобы сделать так:

static_cast<const char*>(someCString) 

Есть ли лучше или более правильный подход к этому?

следующие строки генерировать это предупреждение:

CString str; 
fprintf(pFile, "text %s", str); 
+0

показать нам один из сайтов вызовов, которые дают это предупреждение, с полным декларированием переменных. –

+0

Вы изучили метод-член 'GetBuffer (int minBufferLength)'? Он возвращает «LPSTR» с нулевым завершением, который, по моему мнению, в основном такой же, как «char *», но это не 'const'. Подробнее здесь: http://msdn.microsoft.com/en-us/library/aa314880(v=vs.60).aspx – olevegard

+1

При поддержке MS или нет, это ужасная практика, и я бы PiP ваш коллега за продвигая его. Я еще ничего не вижу от MS, что * конкретно * говорит, что делать это все хорошо и хорошо, и на самом деле их документы специально говорят о том, чтобы передать в LPCTSTR для запуска оператора трансляции. Их реализация «поддерживает» его; для них. Стандарт языка превосходит их, хотят ли они признать это или нет. Если есть подраздел стандарта, который указывает на это как совместимый, я еще не видел его. – WhozCraig

ответ

2

Я предполагаю, что вы передаете «CString» объект Microsoft к Е() - функция семьи, где соответствующий формат спецификатор %s. Если я прав, то ваш ответ здесь: How can CString be passed to format string %s? (словом, ваш код в порядке).

Кажется, что изначально деталь реализации позволила передать CString непосредственно printf(), а затем была включена в контракт. Таким образом, вы хорошо согласны с тем, что ваша программа правильная, но если вы хотите избежать предупреждения статического анализа, вам действительно может понадобиться использовать static_cast для указателя на char. Я не уверен, что это того стоит. Может быть, есть и другой способ сделать эти инструменты хорошими вместе, так как они все от Microsoft.

0

Технически это нормально, потому что c-строка хранится таким образом в CString, что вы можете использовать ее, как указано, но не стоит полагаться на то, как CString реализуется для выполнения ярлыка. printf является функцией C-runtime и ничего не знает о объектах C++, но здесь полагается на то, что строка сначала хранится в CString - деталь реализации.

Если я правильно помню, CString не мог использоваться таким образом, и нужно было приложить CString к c-строке, чтобы распечатать ее, но в более поздних версиях MS изменила реализацию, чтобы позволить ей обрабатываться как c -string.

Еще одна проблема, связанная с UNICODE, это определенно не сработает, если вы когда-нибудь решите скомпилировать программу с набором символов UNICODE, поскольку даже если вы изменили все форматированные строки на% ld, встраиваемые 0 иногда будут препятствовать печати строки ,

Реальная проблема заключается в том, почему вы используете printf вместо C++ для печати/записи файлов?

+0

Некоторые из этих кодов датируются примерно до 25 лет назад, заменяя printf, здесь не вариант. –

+0

Я знаю, что такое чувство: o) vår kod är från -83 –

2

Следуя рекомендациям MSDN в C6284, вы можете отбросить предупреждения. Использование C++-бросков будет наиболее удобным вариантом для этого.Ваш пример выше изменится на

fprintf(pFile, "text %s", static_cast<const TCHAR*>(str)); 

или, просто еще один написание того же, чтобы

fprintf(pFile, "text %s", static_cast<LPCTSTR>(str)); 

Наиболее убедительный вариант (100% литой бесплатно см Edits раздел) является

fprintf(pFile, "text %s", str.GetString()); 

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


изменение: (в соответствии с комментарием xMRi)

1) Я добавил const, потому что аргумент только для чтения для fprintf

2) примечаний к отлитому раствору без CSimpleStringT::GetString: шаблон класса CSimpleStringT используется для определения CStringT, который снова используется для typedef класса CString, который используется в исходном вопросе

3) переработан ответ для устранения шума.

4) уменьшили интро о возможности литья

+0

Зачем мне бросать в TCHAR * вместо использования GetBuffer()? –

+0

Чтобы подвести итог, если мы рассматриваем перенос системы, нам нужно что-то сделать с ошибками. Но если я просто хочу избавиться от предупреждений, вы можете отправить его в TCHAR *? –

+0

@ k4rlsson (1) Как я понимаю, 'GetBuffer()' выделяет память, которая должна быть освобождена вызовом метода ReleaseBuffer(). Это может также иметь отношение к производительности. (2) Если бросок заставляет предупреждение инструмента анализа уйти (я не могу это проверить), я бы использовал его. Это также хорошая возможность просмотреть, если все миллиарды предупреждений на самом деле одинаковы. – Wolf

Смежные вопросы