Skip to content

include/cxx/{cstdlib,cmath}: Provide std::abs(float) overloads - #19891

Open
mpflanzer wants to merge 1 commit into
apache:masterfrom
chickadee-engineering:pflanzem-std-abs
Open

include/cxx/{cstdlib,cmath}: Provide std::abs(float) overloads#19891
mpflanzer wants to merge 1 commit into
apache:masterfrom
chickadee-engineering:pflanzem-std-abs

Conversation

@mpflanzer

@mpflanzer mpflanzer commented Aug 17, 2026

Copy link
Copy Markdown

Summary

The new overloads of std::abs added to cstdlib and cmath are defined as specified by the C++ standard: https://en.cppreference.com/cpp/numeric/math/fabs

Without these new definitions the int std::abs(int) function, provided by using ::abs, was selected for all argument types resulting in a truncation of the result.

Impact

Improved compatibility with the C++ standard

Testing

#include <cstdio>
#include <cstdlib>
#include <float.h>

extern "C" int main(int argc, FAR char *argv[]) {
  printf("FLT_MAX = %f\n", FLT_MAX);
  printf("DBL_MAX = %f\n", DBL_MAX);
  printf("INT_MAX = %d\n", INT_MAX);
  printf("LONG_MAX = %ld\n", LONG_MAX);
  printf("LLONG_MAX = %lld\n", LLONG_MAX);

  printf("::abs(FLT_MAX) = %d\n", ::abs(4.2));
  printf("::abs(DBL_MAX) = %d\n", ::abs(4.2));
  printf("::abs(INT_MAX) = %d\n", ::abs(INT_MAX));
  printf("::abs(LONG_MAX) = %ld\n", ::abs(LONG_MAX));
  printf("::abs(LLONG_MAX) = %lld\n", ::abs(LLONG_MAX));
  printf("std::abs(FLT_MAX) = %f\n", std::abs(FLT_MAX));
  printf("std::abs(DBL_MAX) = %f\n", std::abs(DBL_MAX));
  printf("std::abs(INT_MAX) = %d\n", std::abs(INT_MAX));
  printf("std::abs(LONG_MAX) = %ld\n", std::abs(LONG_MAX));
  printf("std::abs(LLONG_MAX) = %lld\n", std::abs(LLONG_MAX));

  return 0;
}

Without the changes running this program results in the following output:

FLT_MAX = 340282346638529000000000000000000000000.000000
DBL_MAX = 179769313486232000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000000
INT_MAX = 2147483647
LONG_MAX = 2147483647
LLONG_MAX = 9223372036854775807
::abs(FLT_MAX) = 4
::abs(DBL_MAX) = 4
::abs(INT_MAX) = 2147483647
::abs(LONG_MAX) = 2147483647
::abs(LLONG_MAX) = 19327352830
std::abs(FLT_MAX) = 0.000000
std::abs(DBL_MAX) = 0.000000
std::abs(INT_MAX) = 2147483647
std::abs(LONG_MAX) = 2147483647
std::abs(LLONG_MAX) = 19327352830

That is compliant for ::abs but not for std::abs.

With the changes the right overloads of std::abs are selected and the output is:

FLT_MAX = 340282346638529000000000000000000000000.000000
DBL_MAX = 179769313486232000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000000
INT_MAX = 2147483647
LONG_MAX = 2147483647
LLONG_MAX = 9223372036854775807
::abs(FLT_MAX) = 4
::abs(DBL_MAX) = 4
::abs(INT_MAX) = 2147483647
::abs(LONG_MAX) = 2147483647
::abs(LLONG_MAX) = 19327352830
std::abs(FLT_MAX) = 340282346638529000000000000000000000000.000000
std::abs(DBL_MAX) = 179769313486232000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.000000
std::abs(INT_MAX) = 2147483647
std::abs(LONG_MAX) = 2147483647
std::abs(LLONG_MAX) = 9223372036854775807

Tested with the qemu-armv7a:nsh config

@github-actions github-actions Bot added the Size: S The size of the change in this PR is small label Aug 17, 2026
Comment thread include/cxx/bits/std_abs.h Outdated
@mpflanzer

Copy link
Copy Markdown
Author

How shall I address the style errors in the std_abs.h file? It currently follows the same style as the other files in the cxx directory. Those seem pass unchecked because they don't have a .h extension.

Comment thread include/cxx/bits/std_abs.h Outdated
Comment thread include/cxx/bits/std_abs.h Outdated
Comment thread include/cxx/bits/std_abs.h Outdated
Comment thread include/cxx/bits/std_abs.h Outdated
Comment thread include/cxx/cmath Outdated
@mpflanzer
mpflanzer force-pushed the pflanzem-std-abs branch 3 times, most recently from 8f1617f to 94f62fb Compare August 19, 2026 07:17
jerpelea
jerpelea previously approved these changes Aug 19, 2026
@github-actions

github-actions Bot commented Aug 19, 2026

Copy link
Copy Markdown

MemBrowse Memory Report

No memory changes detected for:

@xiaoxiang781216

Copy link
Copy Markdown
Contributor

The overloads of std::abs are defined in cstdlib and cmath according to
the C++ standard.

Without these new definitions the `int std::abs(int)` function was
selected for all argument types resulting in a truncation of the return
values.

Signed-off-by: Moritz Pflanzer <moritz@chickadee-engineering.com>
@mpflanzer

Copy link
Copy Markdown
Author

@mpflanzer please fix ci error: https://github.com/apache/nuttx/actions/runs/32227114781/job/96215519806?pr=19891

That seems a bit of an issue. I think the underlying problem is that Nuttx still adds its own include/cxx directory to the compiler's search path even if CONFIG_LIBCXXTOOLCHAIN is selected. That option only seem to control whether --nostdinc++ is passed to the compiler or not. Having both sets of C++ headers is then causing problems to find the right functions.

To avoid this situation without having to touch any of the include behavior I cannot include math.h and stdlib.h in the bits/std_abs.h helper and the bits directory needs to be renamed to something else as it conflicts with the directory provided by the gcc toolchain.

I now forward declare the abs variants in the std_abs.h helper file (instead of including the other headers) and renamed the directory (from bits to nuttx). Let me know if that is fine or if you would like to do it differently.

I run the failing OOT test locally and it is now passing. My custom test is still behaving correctly with the new changes (same output as before). I also tested this one now with both settings of CONFIG_LIBCXXTOOLCHAIN.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Size: S The size of the change in this PR is small

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants