nicolasWDC opened a new issue, #19059:
URL: https://github.com/apache/nuttx/issues/19059
### Description / Steps to reproduce the issue
# Bug report: `include/cxx/cmath` does not expose `std::log` / `std::pow`
when `FLT_EVAL_METHOD` is only available as `__FLT_EVAL_METHOD__`
## Summary
With NuttX 12.13.0, `include/cxx/cmath` may fail to expose standard C math
symbols such as `std::log` and `std::pow` when `CONFIG_LIBM_TOOLCHAIN` is
disabled.
The C symbols are correctly declared by NuttX `math.h` as `::log` and
`::pow`, and the compiler defines `__FLT_EVAL_METHOD__`, but `FLT_EVAL_METHOD`
is not defined at the point where `include/cxx/cmath` checks it.
As a result, this block is skipped:
```cpp
#if defined(CONFIG_HAVE_DOUBLE) && defined(FLT_EVAL_METHOD) &&
FLT_EVAL_METHOD == 0
using ::log;
using ::pow;
#endif
```
This causes valid C++ code including `<cmath>` to fail when using `std::log`
or `std::pow`.
## Environment
* NuttX version: 12.13.0
* Target: ARM Cortex-M, baremetal NuttX
* Toolchain: `arm-none-eabi-g++` 12.3.1
* C++ standard: `gnu++20`
* `CONFIG_LIBM_TOOLCHAIN` is not enabled
* NuttX headers are used with:
* `-isystem /build/nuttx/include/cxx`
* `-isystem /build/nuttx/include`
## Minimal reproducer
```cpp
#include <cmath>
int test_cmath_symbols()
{
double x = 2.0;
return static_cast<int>(std::log(x) + std::pow(x, 2.0));
}
```
Build command example:
```sh
arm-none-eabi-g++ \
-std=gnu++20 \
-mlittle-endian -march=armv7e-m -mtune=cortex-m4 \
-mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb \
-DCONFIG_WCHAR_BUILTIN -D__NuttX__ \
-isystem /build/nuttx/include/cxx \
-isystem /build/nuttx/include \
-c /tmp/test_cmath.cpp -o /tmp/test_cmath.o
```
## Actual result
```text
/tmp/test_cmath.cpp: In function 'int test_cmath_symbols()':
/tmp/test_cmath.cpp:5:34: error: 'log' is not a member of 'std'; did you
mean 'log'?
5 | return static_cast<int>(std::log(x) + std::pow(x, 2.0));
| ^~~
In file included from /build/nuttx/include/cxx/cmath:42,
from /tmp/test_cmath.cpp:1:
/build/nuttx/include/math.h:327:13: note: 'log' declared here
327 | double log (double x);
| ^~~
/tmp/test_cmath.cpp:5:48: error: 'pow' is not a member of 'std'; did you
mean 'pow'?
5 | return static_cast<int>(std::log(x) + std::pow(x, 2.0));
| ^~~
/build/nuttx/include/math.h:246:13: note: 'pow' declared here
246 | double pow (double b, double e);
| ^~~
```
## Expected result
The program should compile successfully. Since NuttX `math.h` declares the C
symbols, `include/cxx/cmath` should import them into namespace `std` when the
compiler floating-point evaluation method is known to be zero.
## Additional diagnostics
The compiler defines `__FLT_EVAL_METHOD__`, but `FLT_EVAL_METHOD` is not
visible after including `<cmath>`:
```sh
echo '#include <cmath>' | arm-none-eabi-g++ \
-std=gnu++20 \
-mlittle-endian -march=armv7e-m -mtune=cortex-m4 \
-mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb \
-DCONFIG_WCHAR_BUILTIN -D__NuttX__ \
-isystem /build/nuttx/include/cxx \
-isystem /build/nuttx/include \
-dM -E -x c++ - | grep "CONFIG_HAVE_DOUBLE\|FLT_EVAL_METHOD"
```
Output:
```text
#define __FLT_EVAL_METHOD__ 0
#define __FLT_EVAL_METHOD_TS_18661_3__ 0
#define CONFIG_HAVE_DOUBLE 1
```
There is no `FLT_EVAL_METHOD` macro, only the compiler builtin
`__FLT_EVAL_METHOD__`.
## Root cause
`include/cxx/cmath` depends on `FLT_EVAL_METHOD` to decide whether to import
C math functions into `std::`.
However, in this configuration, only `__FLT_EVAL_METHOD__` is defined by the
compiler. The standard macro `FLT_EVAL_METHOD` is not available when `cmath`
evaluates its guards.
NuttX `math.h` has logic to temporarily define `FLT_EVAL_METHOD` from
`__FLT_EVAL_METHOD__`, but that macro may not remain available for the later
checks in `include/cxx/cmath`.
## Proposed fix
In the non-`CONFIG_LIBM_TOOLCHAIN` path of `include/cxx/cmath`, define
`FLT_EVAL_METHOD` locally from `__FLT_EVAL_METHOD__` when needed, before
evaluating the namespace import guards.
Example:
```cpp
# include <math.h>
# if !defined(FLT_EVAL_METHOD) && defined(__FLT_EVAL_METHOD__)
# define FLT_EVAL_METHOD __FLT_EVAL_METHOD__
# define __NUTTX_CXX_CMATH_TMP_FLT_EVAL_METHOD
# endif
```
And clean it up before leaving the NuttX `cmath` shim path:
```cpp
# ifdef __NUTTX_CXX_CMATH_TMP_FLT_EVAL_METHOD
# undef FLT_EVAL_METHOD
# undef __NUTTX_CXX_CMATH_TMP_FLT_EVAL_METHOD
# endif
```
This keeps the recent `CONFIG_LIBM_TOOLCHAIN` behavior unchanged and only
fixes the NuttX `cmath` shim path.
### On which OS does this issue occur?
[OS: Linux]
### What is the version of your OS?
Ubuntu 22.04
### NuttX Version
master
### Issue Architecture
[Arch: all]
### Issue Area
[Area: Posix]
### Host information
_No response_
### Verification
- [x] I have verified before submitting the report.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]