6

I am using Clang 5 on Windows via clang-cl and have run into a problem trying to turn off runtime type information (-fno-rtti) when using std::function.

Here's my example that won't compile:

#include <functional>

void foo(std::function<void()> ra2)
{
}

int main()
{
    auto bar = []()
    {
    };

    foo(bar);

    return EXIT_SUCCESS;
}

Command line:

clang-cl test.cpp -Xclang -fno-rtti

The error is:

C:\Program Files (x86)\Microsoft Visual Studio\Preview\Community\VC\Tools\MSVC\14.13.26128\include\functional(435,11):  error:
      cannot use typeid with -fno-rtti
                return (typeid(_Callable));
                        ^

This surprises me, is there a way to use std::function with lambdas in Clang without RTTI? The docs say that only target and target_type on std::function should need RTTI. I can roll my own version of std::function, but it seems a shame to have to do so.

It works fine if I use MSVC with compiler flag /GR-.

tambre
  • 4,625
  • 4
  • 42
  • 55
keith
  • 5,122
  • 3
  • 21
  • 50
  • 1
    This is not really due to Clang itself, but rather due to using the MSVC standard library, which apparently requires RTTI for `std::function`. Does MSVC itself support `std::function` with RTTI off? If yes, then it's likely a bug in the MSVC Clang compatibility driver. – tambre Dec 23 '17 at 07:43
  • +1 @tabre. It compiles fine (with `-fno-rtti`) both with [libstdc++](https://godbolt.org/g/BQPfhY) and [libc++](https://godbolt.org/g/gDV28z). (Clang5) – BiagioF Dec 23 '17 at 07:55
  • @tambre, yes it compiles with no RTTI in msvc (compiler flag `/GR-`) – keith Dec 23 '17 at 08:04
  • @keith Try defining `_HAS_STATIC_RTTI` to `0` in the compiler options or before including any standard library headers. If it works, then I'm very certain that it's a bug in the Clang compatibility driver for MSVC. – tambre Dec 23 '17 at 09:08
  • @tambre defining `_HAS_STATIC_RTTI` to `0` does seem to strip RTTI from the binary in clang-cl. – keith Dec 23 '17 at 10:01
  • @keith I'll post an answer of my comment then and see if I can open a bug report for Clang. Also, a side note, your program uses `EXIT_SUCCESS`, which is only guaranteed to be defined in `cstdlib`, so it's technically non-portable. – tambre Dec 23 '17 at 10:15
  • @tambre, you are a life saver! – keith Dec 23 '17 at 10:20
  • @tambre, as an aside, why are the things in not portable? – keith Dec 23 '17 at 10:53
  • 2
    @keith They are. But you are using [`EXIT_SUCCESS`](http://en.cppreference.com/w/cpp/utility/program/EXIT_status), which comes from `cstdlib`. But you don't actually include `cstdlib`, which is the only header guaranteed to define `EXIT_SUCCESS`. Your code still compiles compiles due to the specifics of the implementation of the given standard library. The fix to make the code portable from the standard's point of view is to simply include `cstdlib`. – tambre Dec 23 '17 at 11:11

1 Answers1

7

This is a bug fixed in Clang 13.


The Clang MSVC driver fails to define _HAS_STATIC_RTTI to 0, which is used by the MSVC standard library to enable no-RTTI code.

As a workaround you can manually define it globally using compiler flags or defining it before including any standard library headers.

tambre
  • 4,625
  • 4
  • 42
  • 55
  • 1
    Unfortunately this workaround no longer works with the latest version of the MSVC standard library (`c:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.12.25827/include/functional`). The `#if` selects from either `typeid(_Callable)` or `typeid(void)` and both cause the same error `cannot use typeid with -fno-rtti`. – Hugues Feb 11 '18 at 06:52
  • 1
    That error can be worked around by using -Xclang -fno-rtti-data -D_HAS_STATIC_RTTI 0 The clang-cl driver uses -fno-rtti-data when you pass the MS-style /GR- flag but the clang++ driver doesn't expose that by default. So -Xclang is needed to force the driver to accept that -fno-rtti-data parameter. – Honeybunch Jan 08 '19 at 15:54
  • I've just encountered this issue when trying to set up a make file project on windows calling clang++ directly. I added the define and the -Xclang -fno-rtti-data flag and I still get the error as reported – Teknogrebo Jul 25 '19 at 15:38
  • @Teknogrebo, it doesn't work with `-fno-rtti -Xclang -fno-rtti-data`. `clang-cl.exe` translates the `/GR-` flag as `-frtti -Xclang -fno-rtti-data`. – Chris Aug 12 '20 at 05:46