-
Notifications
You must be signed in to change notification settings - Fork 123
Description
Summary
When compiling code that uses nvblox with clang, a build error occurs in nvblox/sensors/internal/impl/image_impl.h. The error, cannot assign to return value because function 'operator()' returns a const value, is triggered because MaskedImageView::setMasked() attempts to modify a value returned by a const operator(). This issue is not present when compiling with gcc, indicating stricter const-correctness enforcement by clang.
Build Environment
- Compiler:
clang++(LLVM version 18) - C++ Standard: C++20
- Operating System: Linux
Steps to Reproduce
To reproduce the error, you can use the following minimal example. This code snippet isolates the problematic behavior by creating a MaskedImageView and calling setMasked(), which triggers the const-correctness error with clang.
1. Create a C++ source file
Create a file named repro.cpp:
#include <nvblox/sensors/image.h>
int main(int argc, char** argv) {
// Dummy data
constexpr int rows = 10;
constexpr int cols = 10;
float image_data[rows * cols] = {0.0f};
unsigned char mask_data[rows * cols] = {0};
// Create ImageViews (non-owning wrappers)
nvblox::ImageView<float> image_view(rows, cols, image_data);
nvblox::ImageView<const unsigned char> mask_view(rows, cols, mask_data);
// Create a MaskedImageView
nvblox::MaskedImageView<float> masked_image_view(image_view, mask_view);
// This call fails to compile with clang because mask_view.operator() is const
// and returns a const reference, which can't be assigned to.
masked_image_view.setMasked(5, 5);
return 0;
}2. Create a CMakeLists.txt
Create a CMakeLists.txt file in the same directory:
cmake_minimum_required(VERSION 3.16)
project(nvblox_repro LANGUAGES CXX CUDA)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Find the dependencies for nvblox
find_package(glog REQUIRED)
find_package(gflags REQUIRED)
find_package(stdgpu REQUIRED)
find_package(CUDA REQUIRED)
find_package(nvblox REQUIRED)
add_executable(repro repro.cpp)
target_link_libraries(repro PRIVATE nvblox::nvblox_lib)3. Configure and Build with Clang
Configure and build the project using clang as the compiler. This will fail at the build step.
export CC=/usr/bin/clang
export CXX=/usr/bin/clang++
cmake -B build
cmake --build buildThe build will fail with the error described in the log below.
Build Error Log
Here is the relevant output from the build failure:
[ 50%] Building CXX object CMakeFiles/repro.dir/repro.cpp.o
In file included from /home/dkar/deps/nvblox/repro_test/repro.cpp:1:
In file included from /usr/local/include/nvblox/sensors/image.h:518:
/usr/local/include/nvblox/sensors/internal/impl/image_impl.h:265:27: error: cannot assign to return value because function 'operator()' returns a const value
265 | mask_(row_idx, col_idx) = image::kMaskedValue;
| ~~~~~~~~~~~~~~~~~~~~~~~ ^
/usr/local/include/nvblox/sensors/image.h:132:30: note: function 'operator()' which returns const-qualified type 'ElementType &' (aka 'const unsigned char &') declared here
132 | __host__ __device__ inline ElementType& operator()(const int row_idx,
| ^~~~~~~~~~~~
1 error generated.
gmake[2]: *** [CMakeFiles/repro.dir/build.make:79: CMakeFiles/repro.dir/repro.cpp.o] Error 1
gmake[1]: *** [CMakeFiles/Makefile2:87: CMakeFiles/repro.dir/all] Error 2
gmake: *** [Makefile:91: all] Error 2
Code Analysis
The error occurs in nvblox/sensors/internal/impl/image_impl.h at line 265, within the MaskedImageView<ElementType>::setMasked function:
// nvblox/sensors/internal/impl/image_impl.h:265
mask_(row_idx, col_idx) = image::kMaskedValue;The mask_ member is an ImageView<unsigned char>. Its operator() is defined in nvblox/sensors/image.h as a const method that returns a const reference, which prevents modification of the underlying data.
// nvblox/sensors/image.h:~132 (inside ImageView)
__host__ __device__ inline const ElementType& operator()(const int row_idx,
const int col_idx) const {
return get(row_idx, col_idx);
}To allow modification, a non-const overload of operator() is probably needed in the ImageView class.
Workaround
A temporary workaround that resolves the immediate compilation issue is to use const_cast at the call site in image_impl.h:
// nvblox/sensors/internal/impl/image_impl.h:265
const_cast<unsigned char&>(mask_(row_idx, col_idx)) = image::kMaskedValue;While this works, adding the non-const overload is the more correct and robust solution.