如何 link 带有调试符号的 libc++?
How to link libc++ with debug symbols?
我想让 std::optional
在用户请求空值时抛出异常。
#include <optional>
std::optional<int> oi;
int main(){
*oi; // Must throw
}
c++ -std=c++17 test.cc && ./a.out
工作没有错误。
我发现在 clang 的 libc++
实现中。
_LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
value_type& value()
{
if (!this->__engaged_)
__throw_bad_optional_access();
return this->__val_;
}
_LIBCPP_INLINE_VISIBILITY
value_type&
operator*()
{
_LIBCPP_ASSERT(this->__engaged_, "optional operator* called for disengaged value");
return this->__val_;
}
然后我找到了llvm libc++ DebugMode
c++ -std=c++2a -D_LIBCPP_DEBUG -D_LIBCPP_DEBUG_USE_EXCEPTIONS ./main.cc && ./a.out
输出
Undefined symbols for architecture x86_64:
"std::__1::__libcpp_db::__insert_c(void*)", referenced from:
void std::__1::__libcpp_db::__insert_c<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*) in main-eef9ea.o
"std::__1::__libcpp_db::swap(void*, void*)", referenced from:
...
如何 link 带有调试符号的 libc++?
P.S.
c++ --version
Apple LLVM version 10.0.1 (clang-1001.0.46.4)
Target: x86_64-apple-darwin18.7.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
便携式解决方法。
#include <optional>
// The same as std::optional, but
// throw and exception when ask for empty value.
// Use assert(0) when exceptions disabled.
template<typename T_>
struct Result : std::optional<T_>{
using T = T_;
using parent = std::optional<T_>;
using parent::parent;
using typename parent::value_type;
using parent::operator bool;
constexpr
const value_type&
operator*() const
{
ensure_is_engaged();
return this->value();
}
value_type&
operator*()
{
ensure_is_engaged();
return this->value();
}
private:
void ensure_is_engaged(){
if( bool is_disengaged = not bool(*this) )
#if __EXCEPTIONS
throw std::runtime_error("failed to get disengaged value from std::optional");
#else
assert(0 && "failed to get disengaged value from std::optional");
#endif
}
};
测试
int main()
{
using std::cout, std::cerr, std::endl;
Result<int> normal=1, fail;
cout<<*normal<<*fail;
}
c++ -std=c++17 -fno-exceptions test.cc && ./a.out
1
Assertion failed: (0 && "failed to get disengaged value from std::optional"), function ensure_is_engaged, file ./result.hh, line 38.
fish: './a.out' terminated by signal SIGABRT (Abort)
c++ -std=c++17 test.cc && ./a.out
假设默认 -fexceptions
1
libc++abi.dylib: terminating with uncaught exception of type std::runtime_error: failed to get disengaged value from std::optional
fish: './a.out' terminated by signal SIGABRT (Abort)
我想让 std::optional
在用户请求空值时抛出异常。
#include <optional>
std::optional<int> oi;
int main(){
*oi; // Must throw
}
c++ -std=c++17 test.cc && ./a.out
工作没有错误。
我发现在 clang 的 libc++
实现中。
_LIBCPP_INLINE_VISIBILITY _LIBCPP_AVAILABILITY_BAD_OPTIONAL_ACCESS
value_type& value()
{
if (!this->__engaged_)
__throw_bad_optional_access();
return this->__val_;
}
_LIBCPP_INLINE_VISIBILITY
value_type&
operator*()
{
_LIBCPP_ASSERT(this->__engaged_, "optional operator* called for disengaged value");
return this->__val_;
}
然后我找到了llvm libc++ DebugMode
c++ -std=c++2a -D_LIBCPP_DEBUG -D_LIBCPP_DEBUG_USE_EXCEPTIONS ./main.cc && ./a.out
输出
Undefined symbols for architecture x86_64:
"std::__1::__libcpp_db::__insert_c(void*)", referenced from:
void std::__1::__libcpp_db::__insert_c<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*) in main-eef9ea.o
"std::__1::__libcpp_db::swap(void*, void*)", referenced from:
...
如何 link 带有调试符号的 libc++?
P.S.
c++ --version
Apple LLVM version 10.0.1 (clang-1001.0.46.4)
Target: x86_64-apple-darwin18.7.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
便携式解决方法。
#include <optional>
// The same as std::optional, but
// throw and exception when ask for empty value.
// Use assert(0) when exceptions disabled.
template<typename T_>
struct Result : std::optional<T_>{
using T = T_;
using parent = std::optional<T_>;
using parent::parent;
using typename parent::value_type;
using parent::operator bool;
constexpr
const value_type&
operator*() const
{
ensure_is_engaged();
return this->value();
}
value_type&
operator*()
{
ensure_is_engaged();
return this->value();
}
private:
void ensure_is_engaged(){
if( bool is_disengaged = not bool(*this) )
#if __EXCEPTIONS
throw std::runtime_error("failed to get disengaged value from std::optional");
#else
assert(0 && "failed to get disengaged value from std::optional");
#endif
}
};
测试
int main()
{
using std::cout, std::cerr, std::endl;
Result<int> normal=1, fail;
cout<<*normal<<*fail;
}
c++ -std=c++17 -fno-exceptions test.cc && ./a.out
1
Assertion failed: (0 && "failed to get disengaged value from std::optional"), function ensure_is_engaged, file ./result.hh, line 38.
fish: './a.out' terminated by signal SIGABRT (Abort)
c++ -std=c++17 test.cc && ./a.out
假设默认 -fexceptions
1
libc++abi.dylib: terminating with uncaught exception of type std::runtime_error: failed to get disengaged value from std::optional
fish: './a.out' terminated by signal SIGABRT (Abort)