Существуют ли более эффективные способы устранения предупреждений при компиляции исходного файла буфера протокола?
Для простого прото файла:
message Person {
required int32 id = 1;
required string name = 2;
optional string email = 3;
}
Он был скомпилирован protoc.exe, и результаты используются также в простом тестовом проекте, который в основном не содержит ничего, кроме файлов, созданных протоком.
Я использую msvc10 для создания тестового проекта (x64), после чего он дал мне много предупреждений:
Warning 1 warning C4244: 'return' : conversion from '__int64' to 'int', possible loss of data D:\Work\protobuf-trunk\src\google\protobuf\descriptor.h 1441 1 testProtobuf
...
Warning 11 warning C4267: 'argument' : conversion from 'size_t' to 'int', possible loss of data D:\Work\protobuf-trunk\src\google\protobuf\unknown_field_set.h 142 1 testProtobuf
Warning 12 warning C4267: 'return' : conversion from 'size_t' to 'int', possible loss of data D:\Work\protobuf-trunk\src\google\protobuf\unknown_field_set.h 237 1 testProtobuf
...
Warning 14 warning C4244: '=' : conversion from '__int64' to 'int', possible loss of data D:\Work\protobuf-trunk\src\google\protobuf\io\coded_stream.h 902 1 testProtobuf
Warning 15 warning C4244: 'return' : conversion from '__int64' to 'int', possible loss of data D:\Work\protobuf-trunk\src\google\protobuf\io\coded_stream.h 1078 1 testProtobuf
Warning 16 warning C4267: 'argument' : conversion from 'size_t' to 'google::protobuf::uint32', possible loss of data D:\Work\protobuf-trunk\src\google\protobuf\wire_format_lite_inl.h 663 1 testProtobuf
...
Warning 19 warning C4267: 'return' : conversion from 'size_t' to 'int', possible loss of data D:\Work\protobuf-trunk\src\google\protobuf\wire_format_lite_inl.h 739 1 testProtobuf
Warning 20 warning C4267: 'argument' : conversion from 'size_t' to 'google::protobuf::uint32', possible loss of data D:\Work\protobuf-trunk\src\google\protobuf\wire_format_lite_inl.h 742 1 testProtobuf
Warning 21 warning C4267: 'return' : conversion from 'size_t' to 'int', possible loss of data D:\Work\protobuf-trunk\src\google\protobuf\wire_format_lite_inl.h 743 1 testProtobuf
Warning 22 warning C4267: 'argument' : conversion from 'size_t' to 'int', possible loss of data D:\Work\testProtobuf\testProtobuf\person.pb.cc 211 1 testProtobuf
...
Warning 28 warning C4996: 'std::_Copy_impl': Function call with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'Checked Iterators' C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xutility 2239 1 testProtobuf
Warning 29 warning C4996: 'std::_Copy_impl': Function call with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'Checked Iterators' C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xutility 2239 1 testProtobuf
Есть ли хороший способ решить все эти предупреждения? Любые предложения будут высоко оценены.
пс. сам проект libprotobuf может быть очищен с помощью msvc10 без предупреждения.
[ edit 2013/02/20]
Рабочее решение
:
- установить свойства для тех файлов, созданных протоком .cc:
свойства конфигурации → c/С++ → advanced → отключить определенные предупреждения
Ответы
Ответ 1
Вы можете взломать источник компилятора protoc, чтобы он автоматически вставлял прагмы в сгенерированные файлы.
В src/google/protobuf/compiler/cpp/cpp_file.cc в GenerateHeader(io::Printer* printer)
вокруг строки 94 измените первый вызов printer->Print
на:
// Generate top of header.
printer->Print(
"// Generated by the protocol buffer compiler. DO NOT EDIT!\n"
"// source: $filename$\n"
"\n"
"#ifndef PROTOBUF_$filename_identifier$__INCLUDED\n"
"#define PROTOBUF_$filename_identifier$__INCLUDED\n"
"\n"
"#ifdef _MSC_VER\n"
"# pragma warning(push)\n"
"# pragma warning(disable: 4127 4244 4267)\n"
"#endif\n"
"\n"
"#include <string>\n"
"\n",
"filename", file_->name(),
"filename_identifier", filename_identifier);
Затем в конце ту же функцию со строкой 294 измените последний вызов printer->Print
на:
printer->Print(
"#ifdef _MSC_VER\n"
"# pragma warning(pop)\n"
"#endif\n"
"\n"
"#endif // PROTOBUF_$filename_identifier$__INCLUDED\n",
"filename_identifier", filename_identifier);
Теперь вам просто нужно скомпилировать цель protoc и запустить новый protoc.exe, чтобы иметь прагмы в сгенерированных заголовках.
Ответ 2
Простой подход заключается в использовании заголовка оболочки для включения сгенерированных заголовков protobuf:
#ifndef MESSAGES_WRAPPER_H
#define MESSAGES_WRAPPER_H
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable: 4018 4100 4267)
#endif
#include "messages.pb.h"
#ifdef _MSC_VER
#pragma warning(pop)
#endif
#endif // MESSAGES_WRAPPER_H
Ответ 3
Компилятор вправе выдавать вам эти предупреждения, так как существует риск усечения.
Если преобразования безопасны, используйте явное приведение. Это чище, чем слепое отключение предупреждений.