Ok, I have this strange bug, or behavior I don't understand. If I use -static-libstdc++ link flag in my project, LLDB fails to show underlying type of a pointer. So here is small example. I have the very basic test executable, with only one main.cpp file:
// main.cpp
#include <memory>
class TestBase
{
public:
TestBase() = default;
virtual ~TestBase() = default;
int m_baseInt = 10;
};
class TestDerived : public TestBase
{
public:
TestDerived() = default;
virtual ~TestDerived() override = default;
int m_derivedInt = 20;
};
int main(int,char*[])
{
std::unique_ptr<TestBase> regularBase = std::make_unique<TestBase>();
std::unique_ptr<TestBase> hiddentBase = std::make_unique<TestDerived>();
TestBase*volatile base = hiddentBase.get();
volatile int breakpoint = 10;
++breakpoint;
}
and one CMake file to build it
# CMakeLists.txt
cmake_minimum_required(VERSION 3.19.0 FATAL_ERROR)
project(quick-test VERSION 0.1.0 LANGUAGES CXX C)
add_executable(test-exe "main.cpp")
For ide I use vscode with CodeLLDB module, and so if you look at 'base' variable it will show TestDerived class (as it should):
But with only one chage, by adding -static-libstdc++ link option to my test executable
# CMakeLists.txt
cmake_minimum_required(VERSION 3.19.0 FATAL_ERROR)
project(quick-test VERSION 0.1.0 LANGUAGES CXX C)
add_executable(test-exe "main.cpp")
target_link_options(test-exe PRIVATE -static-libstdc++)
now lldb is incapable to deduce underlying type of a 'base' pointer:
For compilation I used clang 14.0.0 and gcc 11.2.0, but it didn't make any difference.
Why does linking statically c++ std lib causes this, and is there any solution for this accept removing this flag?
Related
Good day. Building program without using cmake
''' g++ -lpthread src/how2thread.cpp src/main.cpp -ggdb3 -std=c++17 -Wextra '''
produces no errors.
Although, using
'''
cmake . && make
'''
generates following build errors:
[ 25%] Building CXX object CMakeFiles/how2thread_lib.dir/src/how2thread.cpp.obj
D:/Scizzors/Dsktp/cpp/how2thread/src/how2thread.cpp: In member function 'how2thread::Request how2thread::Scheduler::get_request()':
D:/Scizzors/Dsktp/cpp/how2thread/src/how2thread.cpp:103:67: error: use of deleted function 'std::lock_guard<_Mutex>::lock_guard(const std::lock_guard<_Mutex>&) [with _Mutex = std::mutex]'
103 | auto m_lock = std::lock_guard<std::mutex>(data_arr_protect);
| ^
In file included from C:/msys64/mingw64/include/c++/12.1.0/mutex:43,
from D:/Scizzors/Dsktp/cpp/how2thread/src/how2thread.hpp:8,
from D:/Scizzors/Dsktp/cpp/how2thread/src/how2thread.cpp:4:
C:/msys64/mingw64/include/c++/12.1.0/bits/std_mutex.h:237:7: note: declared here
237 | lock_guard(const lock_guard&) = delete;
I specify in my header file, that data_arr_protect is std::mutex object
class Scheduler
{
// class for schedule slicers, processors and collecting data
public:
Scheduler(const std::vector<char>& data,
const std::string& mask); // construct and parse data
Request get_request(); // used to get another batch
void write_request(Request&&);
void write_finding(Finding&& find);
using Find_it = decltype(std::declval<std::vector<Finding>&>().cbegin());
Find_it cbegin();
Find_it cend();
const auto& get_slicing_status(){return is_slicing;} //
std::string mask;
#ifndef DEBUG_V
private:
#endif
const size_t slicer_num;
std::queue<Request> data_arr; // consider switching to deQ
std::mutex data_arr_protect;//for mt rw to vec // might be switching to semaphores
std::queue<Actor_processor> proc_instances_q;
std::queue<Actor_slicer> slicer_instances_q;
std::vector<Finding> result_arr;
std::mutex result_protect;//for mt write to vec
protected:
friend class Actor_slicer; // we need access from slicers to mutexes as they're pretty lowlvl
std::vector<std::mutex> char_segments_protect;
std::vector<size_t> finish_line_no;
std::atomic<size_t> is_slicing; // for break cond
};
My cmake file looks next
cmake_minimum_required(VERSION 3.10.0)
project(how2thread
VERSION 0.0.1
DESCRIPTION "simple mt parser app"
LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
file(GLOB_RECURSE src_files src/*.cpp)
add_library(how2thread_lib src/how2thread.cpp src/how2thread.hpp)
add_executable(how2thread src/main.cpp)
target_link_libraries(how2thread PRIVATE how2thread_lib)
target_link_libraries(how2thread PRIVATE Threads::Threads)
What can cause compiler's misinterpretation and how i must fix it?
I tried different linking options, as building my how2thread.cpp file with main.cpp file, although it didn't help. And I do not get errors about undefined class or something, so, I guess, header file being included by .cpp one
Nothing is being misinterpreted. The issue is the following line: (Which appears only in the error message, not the code you show. Please always provide a minimal reproducible example!)
auto m_lock = std::lock_guard<std::mutex>(data_arr_protect);
This is copy-initialization of m_lock from the initializer expression which before C++17 required the type to be move-constructible, which std::lock_guard is not. Direct-initialization with auto (e.g. auto m_lock(std::lock_guard<std::mutex>(data_arr_protect));) would also not work for the same reason.
To compile this line you need to use C++17 or later, but you are asking cmake to set C++14 with
set(CMAKE_CXX_STANDARD 14)
So change the 14 to 17.
Or if you require compatibility with C++14, you will have to avoid the auto initialization idiom for non-movable types:
std::lock_guard<std::mutex> m_lock(data_arr_protect);
Try to make hello world project with external ASM function in CPP.
CMakeLists.txt
cmake_minimum_required(VERSION 3.11)
project(TestProject VERSION 0.1 LANGUAGES CXX ASM)
set_property(SOURCE foo.s APPEND PROPERTY COMPILE_OPTIONS "-x" "assembler-with-cpp")
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
add_executable(TestProject main.cpp foo.s)
target_include_directories(TestProject PUBLIC
"${PROJECT_BINARY_DIR}"
)
foo.s
.text
.globl _foo
_foo:
add %esi, %edi // add x and y
mov %edi, %eax // move result to correct register for return value
ret
main.cpp
#include <iostream>
using namespace std;
int foo(int x, int y);
int main() {
int result = foo(100, 200);
cout << result << endl;
}
I can generate project for my IDE successfully
cmake .. -G Xcode
And if I build it in IDE I get this error:
Error
Undefined symbol: foo(int, int)
And if I try to build from terminal
cmake --build ..
I get error with CMakeCache.txt:
Error: could not load cache
CPP (only) projects builds fine on the machine.
Suppose something wrong with generated CMakeCache.txt but can get it.
CMakeCache.txt:
https://pastebin.com/BSbZfA67
You have declared foo to have C++ linkage but defined it to have C linkage. To fix this problem, declare foo to have C linkage instead:
extern "C" int foo(int x, int y);
I am trying to have a member array in a class with its length specified by the const static int variable for future needs.
My compiler throws an error with it, and I am not sure this is an error about a uniform initialization or array initialization, or both.
Here is the header file:
#ifndef SOUECE_H
#define SOURCE_H
class Test
{
public:
Test();
static const int array_length{2};
double array[array_length];
};
#endif
This is the source file.
#include "source.h"
Test::Test()
:array_length{0} //Typo of array{0}
{
}
These are the problem messages.
[enter image description here][1]
[1]: https://i.stack.imgur.com/IQ2Mk.png
This is the CMake file.
cmake_minimum_required(VERSION 3.0.0)
project(temp VERSION 0.1.0)
include(CTest)
enable_testing()
add_executable(temp main.cpp)
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)
Finally, these are what the compiler is complaining about when I try to build the project.
[main] Building folder: temp
[build] Starting build
[proc] Executing command: /usr/local/bin/cmake --build /Users/USERNAME/Desktop/temp/build --config Debug --target all -j 14 --
[build] [1/2 50% :: 0.066] Building CXX object CMakeFiles/temp.dir/main.cpp.o
[build] FAILED: CMakeFiles/temp.dir/main.cpp.o
[build] /usr/bin/clang++ -g -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.3.sdk -MD -MT CMakeFiles/temp.dir/main.cpp.o -MF CMakeFiles/temp.dir/main.cpp.o.d -o CMakeFiles/temp.dir/main.cpp.o -c ../main.cpp
[build] In file included from ../main.cpp:1:
[build] ../source.h:8:22: error: function definition does not declare parameters
[build] static const int array_length{2};
[build] ^
[build] ../source.h:9:18: error: use of undeclared identifier 'array_length'
[build] double array[array_length];
[build] ^
[build] 2 errors generated.
[build] ninja: build stopped: subcommand failed.
[build] Build finished with exit code 1
I am using macOS 12.0 beta, with VS Code 1.60.2, clang 13.0.0, CMake 3.20.2.
Please let me know if you see any wrong or have any suggestions.
This cannot work:
Test::Test()
:array_length{0}
You cannot set a const static data member in your constructor. A static value has the same value accross all object instances. But as it is also const no instance is allowed to change the value.
Since array_length is static const you have to initialize it like this:
source.h
#ifndef SOUECE_H
#define SOURCE_H
class Test
{
public:
Test();
static const int array_length = 2;
//static const int array_length{2}; this will also work just note that we cannot use constructor initializer list to initialize static data members
double array[array_length];
};
#endif
source.cpp
#include "source.h"
Test::Test()//we cannot use constructor initializer list to initialize array_length
{
}
Note that static const int array_length{2}; will also work but the thing is that in the constructor we cannot use constructor initializer list to initialize static data member.
EDIT:
If you decide to use static const int array_length{2}; then make sure that you have C++11(or later) enabled in your CMakeLists.txt. For this you can add
set (CMAKE_CXX_STANDARD 11)
to your CMakeLists.txt.
Alternatively, you could instead add
target_compile_features(targetname PUBLIC cxx_std_11)
in your CMakeLists.txt. In your case replace targetname with temp since that is the targetname that you have. Check this out for more how to active C++11 in CMake .
I've been working on os X 10.13 with AppleLLVM 9.1.0(clang-902.0.39.1), and example as follow
#include <experimental/optional>
#include <iostream>
template<typename T>
class p {
public:
T value;
p(T& t):value(t){}
p(T const& t):value(t){}
~p() = default;
};
template <typename T1, typename T2>
constexpr auto operator+(p<T1> const &lhs, p<T2> const &rhs) noexcept {
return p<decltype(lhs.value + rhs.value)>(lhs.value + rhs.value);
}
int main(int, char* []) {
p<int> v1(20);
p<int> v2(10);
auto v3 = v1+v2;
std::cout << v3.value <<std::endl;
return 0;
}
compiled with
c++ -std=c++17 -o test test.cpp
it works perfect for I was just trying to use the new feature of return type deduction as referred in N3638 which proposed a written style as
template<typename T> auto f(T t);
However, when I was about to use it in my CMake(3.11.1) organized project with several flags show as follow:
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_FLAGS "-Wall -fpermissive -Wno-unused-parameter -Werror")
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -ggdb3")
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -ggdb3 -DNDEBUG")
it failed to compile telling me "'auto' return without trailing return type; deduced return types are a C++14 extension".
and I've tried the next flag also getting the same result:
set(CMAKE_CXX_FLAGS "-std=c++17")
It mostly look alike a CMake problem failing at environment set, while I got confused about what CMake flags should I set to enable this new feature? Or was it a compiler-related issue?
Sry guys.
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
works absolutely fine.
The problem was caused by an old version dependency library which used "std::auto_ptr" deprecated in c++11 and removed in c++17 (however still compiles in c++11), hence the CMakeLists was dedicated to c++11 standard.
Problem solved.
And in my ubuntu env, the old version library was updated by apt-get.
I met a strange behavior when using add_property of Boost.Python.
Here is the example codes, it simply add two properties (read-only & read-write) to the wrapped class.
#include <boost/python.hpp>
using namespace boost::python;
struct X {
X( int value ) : val( value ) {}
int get_value() const
{ return val; }
void set_value(int value)
{ val = value; }
int val;
};
BOOST_PYTHON_MODULE(hello) {
class_<X>("X", init<int>() )
// NOTE the order
.add_property( "val_r", &X::get_value ) // read-only first
.add_property( "val_rw", &X::get_value, &X::set_value ) // read-write second
;
}
and the build command:
$ g++ -I/usr/include/python2.7 -shared -L/usr/local/lib -o bp.dll bp.cpp -lboost_python -lpython2.7
I'm working in Cygwin x86_64, so the file extension is .dll. As for Ubuntu just change the output extension to .so.
When importing the bp module, it crashes with a Segmentation fault. The core dump file doesn't contain any call stack information.
However, if I change the order of add_property (as below) to add the read-write property first, it works ok.
.add_property( "val_rw", &X::get_value, &X::set_value ) // read-write first
.add_property( "val_r", &X::get_value ) // read-only second
My environment:
Cygwin x86_64
python 2.7.10
gcc 5.4.0
boost: 1.60.0
BTW, there's no problem in Ubuntu 14.04 (64-bit) whatever the add_property order is.
Why would this happen?