【问题标题】:gcc -O3 flag causes -Winline "call is unlikely and code size would grow" warninggcc -O3 标志导致 -Winline “调用不太可能并且代码大小会增长”警告
【发布时间】:2016-04-28 17:34:59
【问题描述】:

我使用的是 Ubuntu 14.04 和 gcc 4.9.3。我遇到了一个奇怪的问题,当我启用 O3 优化时,会弹出一些“不太可能调用并且代码大小会增长 [-Werror=inline]”错误。我的代码中没有 inline 关键字。为什么 gcc 内联会将代码优化到触发它自己的警告的程度?

显然禁用 -Winline 会编译,但有没有更好的方法来解决这个问题?

我正在使用的库是点云库,为了完整起见,代码如下所示。

我的 CMakeLists

cmake_minimum_required(VERSION 2.8)
project(Test)

set(PROJECT_SRCS
${PROJECT_SOURCE_DIR}/Test.cpp
)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -W -Werror -Winline")

# causes error
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3")

find_package( PCL 1.7 REQUIRED )

include_directories(${PCL_INCLUDE_DIRS})

add_executable(${PROJECT_NAME} ${PROJECT_SRCS})

target_link_libraries(${PROJECT_NAME} ${PCL_LIBRARIES})

Test.cpp

#include <string>
#include <vector>

#include "pcl/common/common_headers.h"
#include "pcl/io/obj_io.h"
#include "pcl/io/ply_io.h"
#include "pcl/io/vtk_lib_io.h"
#include "pcl/visualization/pcl_visualizer.h"

int main(){
  pcl::TextureMesh mesh;
  pcl::PointCloud<pcl::PointNormal> xyz;

  pcl::PointNormal point1;
  pcl::PointNormal point2;
  pcl::PointNormal point3;
  point1.x = 0;
  point2.x = 1;
  point3.x = 0;
  point1.y = 0;
  point2.y = 0;
  point3.y = 1;
  point1.z = 2;
  point2.z = 2;
  point3.z = 2;
  xyz.push_back(point1);
  xyz.push_back(point2);
  xyz.push_back(point3);
  pcl::toPCLPointCloud2(xyz, mesh.cloud);

  std::vector<pcl::Vertices> mesh_poly;
  std::vector<Eigen::Vector2f, Eigen::aligned_allocator<Eigen::Vector2f> > mesh_tex;
  pcl::TexMaterial mesh_material;

  pcl::Vertices v;
  v.vertices.push_back(0);
  v.vertices.push_back(1);
  v.vertices.push_back(2);
  mesh_poly.push_back(v);

  Eigen::Vector2f tex1;
  Eigen::Vector2f tex2;
  Eigen::Vector2f tex3;
  tex1(0) = -1.0;
  tex1(1) = 0.0;
  tex2(0) = -1.0;
  tex2(1) = 1.0;
  tex3(0) = 2.0;
  tex3(1) = 0.0;

  mesh_tex.push_back(tex1);
  mesh_tex.push_back(tex2);
  mesh_tex.push_back(tex3);

  mesh_material.tex_file = "lena.png";
  mesh_material.tex_name = "material_0";

  mesh.tex_polygons.push_back(mesh_poly);
  mesh.tex_coordinates.push_back(mesh_tex);
  mesh.tex_materials.push_back(mesh_material);

  pcl::io::saveOBJFile("out.obj", mesh);

  return 0;
}

编辑:更新错误信息

In file included from /usr/local/include/pcl-1.8/pcl/io/obj_io.h:40:0,
                 from /home/david/test/Test.cpp:5:
/usr/local/include/pcl-1.8/pcl/TextureMesh.h: In function ‘int main()’:
/usr/local/include/pcl-1.8/pcl/TextureMesh.h:50:10: error: inlining failed in call to ‘pcl::TexMaterial::~TexMaterial()’: call is unlikely and code size would grow [-Werror=inline]
   struct TexMaterial
          ^
/home/david/test/Test.cpp:37:20: error: called from here [-Werror=inline]
   pcl::TexMaterial mesh_material;
                ^
In file included from /usr/local/include/pcl-1.8/pcl/io/obj_io.h:40:0,
                 from /home/david/test/Test.cpp:5:
/usr/local/include/pcl-1.8/pcl/TextureMesh.h:91:10: error: inlining     failed in call to ‘pcl::TextureMesh::~TextureMesh()’: call is unlikely and code size would grow [-Werror=inline]
   struct TextureMesh
          ^
/home/david/test/Test.cpp:14:20: error: called from here [-Werror=inline]
   pcl::TextureMesh mesh;
                    ^
In file included from /usr/local/include/pcl-1.8/pcl/io/obj_io.h:40:0,
             from /home/david/test/Test.cpp:5:
/usr/local/include/pcl-1.8/pcl/TextureMesh.h:50:10: error: inlining failed in call to ‘pcl::TexMaterial::~TexMaterial()’: call is unlikely and code size would grow [-Werror=inline]
   struct TexMaterial
          ^
/home/david/test/Test.cpp:37:20: error: called from here [-Werror=inline]
   pcl::TexMaterial mesh_material;
                    ^
In file included from /usr/local/include/pcl-1.8/pcl/io/obj_io.h:40:0,
             from /home/david/test/Test.cpp:5:
/usr/local/include/pcl-1.8/pcl/TextureMesh.h:91:10: error: inlining failed in call to ‘pcl::TextureMesh::~TextureMesh()’: call is unlikely and code size would grow [-Werror=inline]
   struct TextureMesh
          ^
/home/david/test/Test.cpp:14:20: error: called from here [-Werror=inline]
   pcl::TextureMesh mesh;
                ^
cc1plus: all warnings being treated as errors
make[2]: *** [CMakeFiles/Test.dir/Test.cpp.o] Error 1
make[1]: *** [CMakeFiles/Test.dir/all] Error 2
make: *** [all] Error 2

【问题讨论】:

  • 你在哪几行得到这个错误?
  • @FabioTurati 请查看最新更新的错误信息
  • 很明显错误是关于 pcl 代码中的内联,而不是你自己的。

标签: c++ gcc compiler-optimization


【解决方案1】:

使用的类/结构可能有内联成员,即使代码中没有明确说明。

例如,pcl::TextureMesh 结构将具有隐式析构函数,根据 C++ 标准:

隐式声明的析构函数是其类的内联公共成员。

【讨论】:

  • 我进入PCL的源代码并添加了一个空的析构函数,错误就消失了!这是否意味着我们应该总是显式声明一个析构函数来避免这种错误?
  • 没有。我想说-Winline 应该仅用于信息/故障排除目的,可能不应该与-Werror 一起使用。
  • 注意:我认为您可以通过添加以下选项强制Winline 仅保留警告,即使使用-Werror(它可能必须在命令行上的-Werror 选项之后) :-Wno-error=inline
【解决方案2】:

请参阅this 并考虑this answer

GCC 会开启自动内联,即使-O3 优化级别上没有inline 关键字。所以,正如NathanOliver 所说,PCL 库中可能有不太可能的可调用代码(不幸的是,我不熟悉它)。 我会将优化级别降低到-O2 或使用fno-inline-functions 禁用激进的内联

【讨论】:

  • 我仍然得到与-O2fno-inline-functions 相同的错误。您认为这更像是 PCL 问题还是 gcc 问题?我更倾向于这是一个 gcc 问题,因为它不应该将代码优化到触发它自己的警告的程度
  • 我认为这是一个PCL问题,主要是因为Michael Burr刚刚指出的。你还有-Winline 标志,不是吗?删除它,因为每当 inlining 失败时它总是会发出警告(并且它会将警告传递给 warnings are errors 标志)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-05-06
  • 2023-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-12
  • 2023-03-29
相关资源
最近更新 更多