Just add build_requires = ('dep1/version1', 'dep1/version2')
to your conanfile.py
:
class MyPackageConan(ConanFile): # ... requires = ("openssl/1.1.1l", ) build_requires = ("jsoncpp/1.9.4", )
Just add build_requires = ('dep1/version1', 'dep1/version2')
to your conanfile.py
:
class MyPackageConan(ConanFile): # ... requires = ("openssl/1.1.1l", ) build_requires = ("jsoncpp/1.9.4", )
If you want to run git submodule update
in your conanfile.py
, you can simple add a self.run()
command after the git clone command
:
self.run("git clone https://github.com/conan-io/hello.git") self.run("cd hello && git submodule update --init --recursive")
self.run("git clone https://github.com/seznam/elasticlient.git -b version-0.2") self.run("cd elasticlient && git submodule update --init --recursive")
Note that you need to cd <directory> && git submodule update
If you want to create a new conan build recipe for a package that already exists, use
conan new hello/0.1
conan new hello/0.1 -t
More info: See packaging docs
When building a library using conan, this is the default conanfile.py
definition for building using CMake
cmake = CMake(self) cmake.configure(source_folder="hello") cmake.build()
You can easily add definitions like this:
cmake.definitions["MY_FLAG"] = "1"
This will generate -DMY_FLAG=1
when calling CMake
Full example:
cmake = CMake(self) cmake.definitions["USE_SYSTEM_CPR"] = "1 cmake.configure(source_folder="elasticlient")" cmake.build()
Note that you need to add all cmake.definitions
calls before calling cmake.configure()
When trying to configure your CMake project using
find_package(Protobuf REQUIRED)
you see an error message like
CMake Error at /usr/share/cmake-3.16/Modules/FindThreads.cmake:49 (message): FindThreads only works if either C or CXX language is enabled Call Stack (most recent call first): /usr/share/cmake-3.16/Modules/FindProtobuf.cmake:420 (find_package) CMakeLists.txt:7 (find_package) -- Configuring incomplete, errors occurred!
You need to put your
project(MyProject)
line before the
find_package(Protobuf REQUIRED)
line. If you don’t have a project()
line, create one.
Use fseek()
with offset -1
and mode SEEK_END
:
fseek(myfile, -1, SEEK_END);
#include <cstdio> #include <optional> /** * Read the last byte of a given */ std::optional<char> readLastByteOfFile(const char* filename) { FILE* fin = fopen(filename, "r"); if(fin == nullptr) { return std::nullopt; } fseek(fin, -1, SEEK_END); char lastByte; if(fread(&lastByte, 1, 1, fin) == 0) { return std::nullopt; } fclose(fin); return lastByte; }
#include <cstdlib> #include <cstdio> #include <iostream> #include <optional> /** * Read the last byte of a given */ std::optional<char> readLastByteOfFile(const char* filename) { FILE* fin = fopen(filename, "r"); if(fin == nullptr) { return std::nullopt; } fseek(fin, -1, SEEK_END); char lastByte; if(fread(&lastByte, 1, 1, fin) == 0) { return std::nullopt; } fclose(fin); return lastByte; } int main(int argc, char** argv) { if(argc < 2) { std::cerr << "Usage: " << argv[0] << " <input file to read from>" << std::endl; } auto lastByte = readLastByteOfFile(argv[1]); if(lastByte) { std::cout << lastByte.value() << std::endl; } else { std::cout << "File error or empty" << std::endl; } }
Generate test data with:
echo -n "abcd" > test.txt touch test2.txt
Compile using:
g++ -o read-last-byte read-last-byte.cpp --std=c++17
Test using:
$ ./test-last-byte test1.txt d $ ./test-last-byte test2.txt File error or no last byte
Use the template argument (<>
) like this:
doc.parse<rapidxml::parse_non_destructive>(data);
// Create & parse document xml_document<> doc; try { doc.parse<rapidxml::parse_non_destructive>(data); } catch(rapidxml::parse_error& ex) { cerr << "XML Parse error in " << filename << endl; return; }
When compiling a piece of software – for example in your Dockerfile
or on your PC – you see a warning message like
lz4 library not found, compiling without it
Install liblz4
, which is a library for a compression algorithm. On Ubuntu/Debian based systems you can install it using
sudo apt -y install liblz4-dev
In your Dockerfile, install using
RUN apt update && apt install -y liblz4-dev && rm -rf /var/lib/apt/lists/*
Otherwise, refer to the liblz4 GitHub page.
In gdb, run
catch throw
in order to break on any exception that is being thrown.
If you want to only break on a specific exception type instead, use
catch throw [exception type]
Add this to your CMakeLists.txt
:
# # Compile test suite # find_package(Boost COMPONENTS system filesystem unit_test_framework REQUIRED) add_executable(test_myprogram tests/MyTest.cpp ) target_include_directories(test_myprogram PUBLIC "${CMAKE_CURRENT_LIST_DIR}/include") target_compile_features(test_myprogram PRIVATE cxx_std_17) target_link_libraries(test_myprogram ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY} ) add_test(test_myprogram test_myprogram) # make "make test" run the test program add_custom_target(test DEPENDS myprogram COMMAND ./test_myprogram )
In order to build the program and the test, run
make
In order to run the tests, use
make test
When compiling your CMake-based C++
CMake Error at /usr/lib/x86_64-linux-gnu/cmake/Boost-1.71.0/BoostConfig.cmake:117 (find_package): Could not find a package configuration file provided by "boost_unit_test_framework" (requested version 1.71.0) with any of the following names: boost_unit_test_frameworkConfig.cmake boost_unit_test_framework-config.cmake Add the installation prefix of "boost_unit_test_framework" to CMAKE_PREFIX_PATH or set "boost_unit_test_framework_DIR" to a directory containing one of the above files. If "boost_unit_test_framework" provides a separate development package or SDK, be sure it has been installed. Call Stack (most recent call first): /usr/lib/x86_64-linux-gnu/cmake/Boost-1.71.0/BoostConfig.cmake:182 (boost_find_component) /usr/share/cmake-3.16/Modules/FindBoost.cmake:443 (find_package) OCCUtils/CMakeLists.txt:58 (find_package) -- Configuring incomplete, errors occurred!
The error message is trying to tell you that you don’t have the boost unit test
library installed (or CMake can’t find it).
On Ubuntu, for example, install it using
sudo apt -y install libboost-test-dev
On Windows you can install it using the prebuilt boost binaries for Windows.
When compiling your CMake-based C++
CMake Error at /usr/lib/x86_64-linux-gnu/cmake/Boost-1.71.0/BoostConfig.cmake:117 (find_package): Could not find a package configuration file provided by "boost_filesystem" (requested version 1.71.0) with any of the following names: boost_filesystemConfig.cmake boost_filesystem-config.cmake Add the installation prefix of "boost_filesystem" to CMAKE_PREFIX_PATH or set "boost_filesystem_DIR" to a directory containing one of the above files. If "boost_filesystem" provides a separate development package or SDK, be sure it has been installed. Call Stack (most recent call first): /usr/lib/x86_64-linux-gnu/cmake/Boost-1.71.0/BoostConfig.cmake:182 (boost_find_component) /usr/share/cmake-3.16/Modules/FindBoost.cmake:443 (find_package) CMakeLists.txt:58 (find_package)
The error message is trying to tell you that you don’t have the boost filesystem
library installed (or CMake can’t find it).
On Ubuntu, for example, install it using
sudo apt -y install libboost-filesystem-dev
On Windows you can install it using the prebuilt boost binaries for Windows.
#define BOOST_TEST_MAIN #include <boost/test/unit_test.hpp> BOOST_AUTO_TEST_CASE( test1 ) { BOOST_CHECK( 2 == 1 ); }
You can use the ESP32Ping library in order to easily ping the current gateway IP:
if(Ping.ping(WiFi.gatewayIP(), 1)) { // 1: Just one ping // TODO What to do on ping succes // Example: Print response time Serial.print(Ping.averageTime()); // Unit: ms Serial.println(" ms"); } else { // TODO What to do if ping failed? }
#include <Arduino.h> #include <WiFi.h> #include <ESP32Ping.h> void waitForWiFiConnectOrReboot(bool printOnSerial=true) { uint32_t notConnectedCounter = 0; while (WiFi.status() != WL_CONNECTED) { delay(100); if(printOnSerial) { Serial.println("Wifi connecting..."); } notConnectedCounter++; if(notConnectedCounter > 50) { // Reset board if not connected after 5s if(printOnSerial) { Serial.println("Resetting due to Wifi not connecting..."); } ESP.restart(); } } if(printOnSerial) { // Print wifi IP addess Serial.println("IP address: "); Serial.println(WiFi.localIP()); } } #define LED_BUILTIN 2 void setup() { Serial.begin(115200); WiFi.begin("MyWifiSSID", "MyWifiPassword"); // Wait for wifi to be connected waitForWiFiConnectOrReboot(); // Initialize LED pinMode(LED_BUILTIN,OUTPUT); } void loop() { if(Ping.ping(WiFi.gatewayIP())) { digitalWrite(LED_BUILTIN,HIGH); Serial.print(Ping.averageTime()); Serial.println(" ms"); } else { digitalWrite(LED_BUILTIN, LOW); Serial.println("Error :("); } }
6.12 ms 5.12 ms 5.11 ms 5.16 ms 4.95 ms 4.88 ms 4.84 ms 7.67 ms 5.01 ms 4.87 ms 4.81 ms 4.80 ms 4.85 ms 5.08 ms 5.76 ms 4.54 ms 5.12 ms 2.77 ms 4.88 ms 4.84 ms 6.07 ms 5.08 ms 4.91 ms 6.04 ms 4.88 ms 4.98 ms 6.43 ms 8.18 ms 4.93 ms 5.17 ms 4.97 ms 5.46 ms 5.88 ms 4.78 ms 4.88 ms 6.03 ms 4.84 ms 5.70 ms 5.94 ms 7.25 ms 5.07 ms 4.78 ms 5.51 ms 4.99 ms 5.04 ms 4.79 ms 4.94 ms 4.81 ms 5.97 ms 5.85 ms 4.83 ms 4.80 ms 4.80 ms 6.29 ms 4.99 ms 5.04 ms 9.21 ms 5.20 ms 6.05 ms 6.14 ms 5.03 ms 4.90 ms 7.22 ms 5.06 ms 4.94 ms 9.03 ms 5.13 ms 11.97 ms 6.32 ms 6.12 ms 4.92 ms 4.92 ms 6.01 ms 4.96 ms 4.98 ms 4.94 ms 6.08 ms 6.11 ms 4.93 ms 5.05 ms 5.78 ms 4.47 ms 6.28 ms 5.02 ms 5.13 ms 5.11 ms 5.19 ms 8.89 ms 5.76 ms 5.18 ms 8.08 ms 4.97 ms 4.89 ms 4.70 ms 5.40 ms 7.46 ms 5.09 ms 4.95 ms 4.96 ms 5.01 ms 5.01 ms 4.89 ms 6.22 ms 6.76 ms 6.92 ms 6.10 ms 9.61 ms 5.29 ms 6.13 ms 5.15 ms 5.02 ms 5.03 ms 5.01 ms 6.13 ms 4.78 ms 3.90 ms 6.27 ms 8.07 ms 5.94 ms 4.50 ms 6.13 ms 4.99 ms 6.07 ms 4.80 ms 4.84 ms 4.95 ms 4.95 ms 6.78 ms 4.88 ms
While trying to compile your C/C++ program, you see an error message like
../src/main.c:48:9: error: implicit declaration of function 'StartBenchmark' [-Werror=implicit-function-declaration] StartBenchmark();
implicit declaration of function
means that you are trying to use a function that has not been declared. In our example above, StartBenchmark
is the function that is implicitly declared.
This is how you call a function:
StartBenchmark();
This is how you declare a function:
void StartBenchmark();
The following bullet points list the most common reasons and how to fix them:
#include
: Check if the header file that contains the declaration of the function is #include
d in each file where you call the function (especially the file that is listed in the error message), before the first call of the function (typically at the top of the file). Header files can be included via other headers,startBenchmark()
is declared while StartBenchmark()
is being called. I recommend to fix this by copy-&-pasting the function name from the declaration to wherever you call it.#ifndef _EXAMPLE_FILE_NAME_H #define _EXAMPLE_FILE_NAME_H // ... #endif
Note that the include guard definition _EXAMPLE_FILE_NAME_H
is not specific to the header filename that we are using (for example Benchmark.h
). Just the first of all header file names wil
#include
statements: While this might seem like a bad hack, it often works just fine. Just move the #include
statements of the header file containing the declaration to the top. For example, before the move:#include "Benchmark.h" #include "other_header.h"
after the move:
#include "Benchmark.h" #include "other_header.h"
First, use MPLab Harmony Configurator 3 to enable the CORETIMER module for your project. No special configuration is neccessary.
The PIC32 Core Timer always runs at half the CPU frequency. For example, if the CPU is running at 200 MHz, the Core Timer will run at 100 MHz.
You an then use
uint32_t CORETIMER_CounterGet();
to get the current value of the core timer. Additionally, you can get the frequency of the Core Timer in Hz
using
uint32_t CORETIMER_FrequencyGet();
Use the following snippet to measure how long it takes to run a specific function:
uint32_t t0 = CORETIMER_CounterGet(); run_my_func(); uint32_t t1 = CORETIMER_CounterGet();
After that, you can compute the number of seconds it took to run the function using e.g.
uint32_t tdelta = t1 - t0; float seconds = tdelta / (float)CORETIMER_FrequencyGet();
or the number of milliseconds:
uint32_t tdelta = t1 - t0; float milliseconds = tdelta / (CORETIMER_FrequencyGet() / 1000.0);
or the number of microseconds:
uint32_t tdelta = t1 - t0; float microseconds = tdelta / (CORETIMER_FrequencyGet() / 1000000.0);
When trying to compile your C++ application, you see lots of undefined reference to
messages like
AutoBenchmark.cpp:(.text+0x6a): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)' /usr/bin/ld: AutoBenchmark.cpp:(.text+0x81): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)' /usr/bin/ld: AutoBenchmark.cpp:(.text+0x8a): undefined reference to `std::chrono::_V2::system_clock::now()' /usr/bin/ld: AutoBenchmark.cpp:(.text+0xcd): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()' /usr/bin/ld: AutoBenchmark.cpp:(.text+0xe6): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()' /usr/bin/ld: /tmp/cc356AdP.o: in function `AutoBenchmark::~AutoBenchmark()': AutoBenchmark.cpp:(.text+0x17e): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()' /usr/bin/ld: AutoBenchmark.cpp:(.text+0x18e): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()' /usr/bin/ld: /tmp/cc356AdP.o: in function `AutoBenchmark::Record(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)': AutoBenchmark.cpp:(.text+0x1db): undefined reference to `std::chrono::_V2::system_clock::now()' /usr/bin/ld: /tmp/cc356AdP.o: in function `AutoBenchmark::Record(char const*)': AutoBenchmark.cpp:(.text+0x252): undefined reference to `std::allocator<char>::allocator()' /usr/bin/ld: AutoBenchmark.cpp:(.text+0x288): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()' /usr/bin/ld: AutoBenchmark.cpp:(.text+0x294): undefined reference to `std::allocator<char>::~allocator()' /usr/bin/ld: AutoBenchmark.cpp:(.text+0x2b9): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string()' /usr/bin/ld: AutoBenchmark.cpp:(.text+0x2ce): undefined reference to `std::allocator<char>::~allocator()' /usr/bin/ld: /tmp/cc356AdP.o: in function `AutoBenchmark::Print()': AutoBenchmark.cpp:(.text+0x316): undefined reference to `std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::length() const' /usr/bin/ld: AutoBenchmark.cpp:(.text+0x332): undefined reference to `std::cout' /usr/bin/ld: AutoBenchmark.cpp:(.text+0x337): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <char, std::char_traits<char>, std::allocator<char> >(std::basic_ostream<char, std::char_traits<char> >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)' /usr/bin/ld: AutoBenchmark.cpp:(.text+0x344): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char)' /usr/bin/ld: AutoBenchmark.cpp:(.text+0x572): undefined reference to `std::cout' /usr/bin/ld: AutoBenchmark.cpp:(.text+0x577): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <char, std::char_traits<char>, std::allocator<char> >(std::basic_ostream<char, std::char_traits<char> >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)' /usr/bin/ld: AutoBenchmark.cpp:(.text+0x59c): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <char, std::char_traits<char>, std::allocator<char> >(std::basic_ostream<char, std::char_traits<char> >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)' /usr/bin/ld: AutoBenchmark.cpp:(.text+0x5ab): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)' /usr/bin/ld: AutoBenchmark.cpp:(.text+0x5c2): undefined reference to `std::ostream::operator<<(double)' /usr/bin/ld: AutoBenchmark.cpp:(.text+0x5d1): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)' /usr/bin/ld: AutoBenchmark.cpp:(.text+0x607): undefined reference to `std::cout' /usr/bin/ld: AutoBenchmark.cpp:(.text+0x60c): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <char, std::char_traits<char>, std::allocator<char> >(std::basic_ostream<char, std::char_traits<char> >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)' /usr/bin/ld: AutoBenchmark.cpp:(.text+0x631): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <char, std::char_traits<char>, std::allocator<char> >(std::basic_ostream<char, std::char_traits<char> >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)' /usr/bin/ld: AutoBenchmark.cpp:(.text+0x640): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)' /usr/bin/ld: AutoBenchmark.cpp:(.text+0x657): undefined reference to `std::ostream::operator<<(double)' /usr/bin/ld: AutoBenchmark.cpp:(.text+0x666): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)' /usr/bin/ld: AutoBenchmark.cpp:(.text+0x69c): undefined reference to `std::cout' /usr/bin/ld: AutoBenchmark.cpp:(.text+0x6a1): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <char, std::char_traits<char>, std::allocator<char> >(std::basic_ostream<char, std::char_traits<char> >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)' /usr/bin/ld: AutoBenchmark.cpp:(.text+0x6c6): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <char, std::char_traits<char>, std::allocator<char> >(std::basic_ostream<char, std::char_traits<char> >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)' /usr/bin/ld: AutoBenchmark.cpp:(.text+0x6d5): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)' /usr/bin/ld: AutoBenchmark.cpp:(.text+0x6ec): undefined reference to `std::ostream::operator<<(double)' /usr/bin/ld: AutoBenchmark.cpp:(.text+0x6fb): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)' /usr/bin/ld: AutoBenchmark.cpp:(.text+0x731): undefined reference to `std::cout' /usr/bin/ld: AutoBenchmark.cpp:(.text+0x736): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <char, std::char_traits<char>, std::allocator<char> >(std::basic_ostream<char, std::char_traits<char> >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)' /usr/bin/ld: AutoBenchmark.cpp:(.text+0x75b): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <char, std::char_traits<char>, std::allocator<char> >(std::basic_ostream<char, std::char_traits<char> >&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)' /usr/bin/ld: AutoBenchmark.cpp:(.text+0x76a): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)' /usr/bin/ld: AutoBenchmark.cpp:(.text+0x781): undefined reference to `std::ostream::operator<<(double)' /usr/bin/ld: AutoBenchmark.cpp:(.text+0x790): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)' /usr/bin/ld: AutoBenchmark.cpp:(.text+0x7c6): undefined reference to `std::cout'
You need to link the stdc++
library by adding -lstdc++
to your compiler/linker flags.
For example, instead of
gcc -o myprogram *.c
use
gcc -o myprogram *.c -lstdc++
When trying to compile an application on Linux, you see a compiler error message like
myheader.h:23:12: error: expected constructor, destructor, or type conversion before ‘(’ token 23 | __declspec(dllexport) int myfunc(
__declspec(dllexport)
is a Windows-specific feature and not available on Linux. In order to fix it in a compatible way, add this code either in a header that is included in every file containing __declspec(dllexport)
or add it in each file where the error occurs:
#ifdef __linux__ #define __declspec(v) #endif
This will basically ignore any __declspec()
call on the preprocessor level.
Problem:
When trying to compile your application using gcc, you see an error message like
/usr/bin/ld: /tmp/ccxPIowU.o: in function `run_mymath': mathstuff.c:(.text+0x15d): undefined reference to `sqrt'
You need to link the math library using the -lm
flag (-lxxx
means: “link the xxx
library”, i.e. -lm
means “link the m
” library)
For example, instead of
gcc -o myprogram *.c
use
gcc -o myprogram *.c -lm
If you’re trying to compile Windows code on Linux, you will often see messages like
lmmin.c:261:10: warning: implicit declaration of function ‘_finite’; did you mean ‘finite’? [-Wimplicit-function-declaration] 116 | if(!_finite(myvalue)){
or
/usr/bin/ld: mymath.c:(.text+0x1057): undefined reference to `_finite'
and your code won’t compile.
_finite
is a function that is only available on Windows. In order to use it on Linux using GCC or G++, one option is to use isfinite()
from math.h
:
#include <math.h> #define _finite(v) (isfinite((v)))
In case that function is not available (like on some Microcontroller platforms), you can use __builtin_isfinite()
. Note that glibc defines isfinite()
as an alias for __builtin_isfinite()
. Use it like this:
#define _finite(v) (__builtin_isfinite(v))
In case you want to have code that is compatible with both platforms (Windows and Linux), use
#ifdef __linux__ #define _finite(v) (__builtin_isfinite(v)) #endif
or
#include <math.h> #ifdef __linux__ #define _finite(v) (isfinite((v))) #endif