Skip to main content
deleted 204 characters in body
Source Link
Rakete1111
  • 2.6k
  • 1
  • 15
  • 23

Is there a situation where the compiler will not optimize away the wrapper because the wrapper and the original function have different semantics?

Yes to the first part and no to the second. Any optimizing compiler will inline your wrapper, as it consists of only one return statement.

But on the other hand, the original function might have different semantics: It might be constexpr for example, and your alias will not be.

Does this fail to compile for some functions?

No (except for the constexpr part).

So here are some improvements you can use:

  1. Do you really need __VA_ARGS__? It looks like FUN_ALIAS is only supposed to be called with two arguments; if I'm not missing something. But at least it's more than one.

  2. Templates are implicitly inline, so you don't need to write it explicitly.

  3. Use a lambda to combat the missing constexprness of the alias, because since C++17 lambdas are implicitly constexpr if they can be.

This will get you:

#define FUN_ALIAS(NEW_NAME, OLD_NAME...)                                                \
  inline auto NEW_NAME = [](auto &&... args)                                        \
    noexcept(noexcept(OLD_NAME__VA_ARGS__(std::forward<decltype(args)>(args)...)))             \
    -> decltype(auto) {                                                             \
    return OLD_NAME__VA_ARGS__(std::forward<decltype(args)>(args)...);                         \
  };

Is there a situation where the compiler will not optimize away the wrapper because the wrapper and the original function have different semantics?

Yes to the first part and no to the second. Any optimizing compiler will inline your wrapper, as it consists of only one return statement.

But on the other hand, the original function might have different semantics: It might be constexpr for example, and your alias will not be.

Does this fail to compile for some functions?

No (except for the constexpr part).

So here are some improvements you can use:

  1. Do you really need __VA_ARGS__? It looks like FUN_ALIAS is only supposed to be called with two arguments; if I'm not missing something. But at least it's more than one.

  2. Templates are implicitly inline, so you don't need to write it explicitly.

  3. Use a lambda to combat the missing constexprness of the alias.

This will get you:

#define FUN_ALIAS(NEW_NAME, OLD_NAME)                                                \
  inline auto NEW_NAME = [](auto &&... args)                                        \
    noexcept(noexcept(OLD_NAME(std::forward<decltype(args)>(args)...)))             \
    -> decltype(auto) {                                                             \
    return OLD_NAME(std::forward<decltype(args)>(args)...);                         \
  };

Is there a situation where the compiler will not optimize away the wrapper because the wrapper and the original function have different semantics?

Yes to the first part and no to the second. Any optimizing compiler will inline your wrapper, as it consists of only one return statement.

But on the other hand, the original function might have different semantics: It might be constexpr for example, and your alias will not be.

Does this fail to compile for some functions?

No (except for the constexpr part).

So here are some improvements you can use:

  1. Templates are implicitly inline, so you don't need to write it explicitly.

  2. Use a lambda to combat the missing constexprness of the alias, because since C++17 lambdas are implicitly constexpr if they can be.

This will get you:

#define FUN_ALIAS(NEW_NAME, ...)                                                \
  inline auto NEW_NAME = [](auto &&... args)                                   \
    noexcept(noexcept(__VA_ARGS__(std::forward<decltype(args)>(args)...)))     \
    -> decltype(auto) {                                                        \
    return __VA_ARGS__(std::forward<decltype(args)>(args)...);                \
  };
Source Link
Rakete1111
  • 2.6k
  • 1
  • 15
  • 23

Is there a situation where the compiler will not optimize away the wrapper because the wrapper and the original function have different semantics?

Yes to the first part and no to the second. Any optimizing compiler will inline your wrapper, as it consists of only one return statement.

But on the other hand, the original function might have different semantics: It might be constexpr for example, and your alias will not be.

Does this fail to compile for some functions?

No (except for the constexpr part).

So here are some improvements you can use:

  1. Do you really need __VA_ARGS__? It looks like FUN_ALIAS is only supposed to be called with two arguments; if I'm not missing something. But at least it's more than one.

  2. Templates are implicitly inline, so you don't need to write it explicitly.

  3. Use a lambda to combat the missing constexprness of the alias.

This will get you:

#define FUN_ALIAS(NEW_NAME, OLD_NAME)                                                \
  inline auto NEW_NAME = [](auto &&... args)                                        \
    noexcept(noexcept(OLD_NAME(std::forward<decltype(args)>(args)...)))             \
    -> decltype(auto) {                                                             \
    return OLD_NAME(std::forward<decltype(args)>(args)...);                         \
  };