Подтвердить что ты не робот

Существуют ли более эффективные способы устранения предупреждений при компиляции исходного файла буфера протокола?

Для простого прото файла:

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 → отключить определенные предупреждения
4b9b3361

Ответ 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

Компилятор вправе выдавать вам эти предупреждения, так как существует риск усечения.

Если преобразования безопасны, используйте явное приведение. Это чище, чем слепое отключение предупреждений.