且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

编译协议缓冲区生成的源文件时,是否有更好的方法来解决警告?

更新时间:2023-11-25 11:26:22

您可以破解 protoc 编译器的源代码,让它自动将编译指示注入生成的文件中.

src/google/protobuf/compiler/cpp/cpp_file.cc 在第 94 行附近的 GenerateHeader(io::Printer* printer) 中,更改第一个 printer->Print 调用到:

//生成头部的顶部.打印机->打印("//由协议缓冲区编译器生成.请勿编辑!
""//来源:$文件名$
""
""#ifndef PROTOBUF_$filename_identifier$__INCLUDED
""#define PROTOBUF_$filename_identifier$__INCLUDED
""
""#ifdef _MSC_VER
""# pragma 警告(推送)
""# pragma warning(disable: 4127 4244 4267)
""#endif
""
""#include 
""
","文件名", 文件_-> 名称(),"filename_identifier", filename_identifier);

然后在 末尾在第 294 行 附近使用相同的函数,将最后一个 printer->Print 调用更改为:

 打印机->打印("#ifdef _MSC_VER
""# pragma 警告(pop)
""#endif
""
""#endif//PROTOBUF_$filename_identifier$__INCLUDED
","filename_identifier", filename_identifier);

现在您只需要编译 protoc 目标并运行新的 protoc.exe 即可在生成的标头中包含编译指示.

For a simple proto file:

message Person {
  required int32 id = 1;
  required string name = 2;
  optional string email = 3;
}

It's been compiled by protoc.exe and the results are used in an also simple test project, which basically does nothing but including the protoc generated files.

I'm using the msvc10 to build the test project (x64), then it gave me a lot of warning:

Warning 1   warning C4244: 'return' : conversion from '__int64' to 'int', possible loss of data D:Workprotobuf-trunksrcgoogleprotobufdescriptor.h 1441    1   testProtobuf
...
Warning 11  warning C4267: 'argument' : conversion from 'size_t' to 'int', possible loss of data    D:Workprotobuf-trunksrcgoogleprotobufunknown_field_set.h  142 1   testProtobuf
Warning 12  warning C4267: 'return' : conversion from 'size_t' to 'int', possible loss of data  D:Workprotobuf-trunksrcgoogleprotobufunknown_field_set.h  237 1   testProtobuf
...
Warning 14  warning C4244: '=' : conversion from '__int64' to 'int', possible loss of data  D:Workprotobuf-trunksrcgoogleprotobufiocoded_stream.h    902 1   testProtobuf
Warning 15  warning C4244: 'return' : conversion from '__int64' to 'int', possible loss of data D:Workprotobuf-trunksrcgoogleprotobufiocoded_stream.h    1078    1   testProtobuf
Warning 16  warning C4267: 'argument' : conversion from 'size_t' to 'google::protobuf::uint32', possible loss of data   D:Workprotobuf-trunksrcgoogleprotobufwire_format_lite_inl.h   663 1   testProtobuf
...
Warning 19  warning C4267: 'return' : conversion from 'size_t' to 'int', possible loss of data  D:Workprotobuf-trunksrcgoogleprotobufwire_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:Workprotobuf-trunksrcgoogleprotobufwire_format_lite_inl.h   742 1   testProtobuf
Warning 21  warning C4267: 'return' : conversion from 'size_t' to 'int', possible loss of data  D:Workprotobuf-trunksrcgoogleprotobufwire_format_lite_inl.h   743 1   testProtobuf
Warning 22  warning C4267: 'argument' : conversion from 'size_t' to 'int', possible loss of data    D:Work	estProtobuf	estProtobufperson.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.0VCincludexutility 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.0VCincludexutility 2239    1   testProtobuf

Is there any good way to address all of these warning? Any suggestions will be greatly appreciated.

ps. the libprotobuf project itself can be clean compiled by msvc10 without any warning.

[edit 2013/02/20]

working solution:

  1. set properties for those protoc generated .cc files:
    configuration properties -> c/c++ -> advanced -> disable specific warnings

You can hack the source of the protoc compiler to have it inject the pragmas into the generated files automatically.

In src/google/protobuf/compiler/cpp/cpp_file.cc in GenerateHeader(io::Printer* printer) around line 94, change the first printer->Print call to:

  // Generate top of header.
  printer->Print(
    "// Generated by the protocol buffer compiler.  DO NOT EDIT!
"
    "// source: $filename$
"
    "
"
    "#ifndef PROTOBUF_$filename_identifier$__INCLUDED
"
    "#define PROTOBUF_$filename_identifier$__INCLUDED
"
    "
"
    "#ifdef _MSC_VER
"
    "#  pragma warning(push)
"
    "#  pragma warning(disable: 4127 4244 4267)
"
    "#endif
"
    "
"
    "#include <string>
"
    "
",
    "filename", file_->name(),
    "filename_identifier", filename_identifier);

Then at the end of the same function at around line 294, change the last printer->Print call to:

  printer->Print(
    "#ifdef _MSC_VER
"
    "#  pragma warning(pop)
"
    "#endif
"
    "
"
    "#endif  // PROTOBUF_$filename_identifier$__INCLUDED
",
    "filename_identifier", filename_identifier);

Now you just need to compile the protoc target and run the new protoc.exe to have the pragmas in the generated headers.