I am trying to have a member array in a class with its length specified by the const static int variable for future needs.
My compiler throws an error with it, and I am not sure this is an error about a uniform initialization or array initialization, or both.
Here is the header file:
#ifndef SOUECE_H
#define SOURCE_H
class Test
{
public:
Test();
static const int array_length{2};
double array[array_length];
};
#endif
This is the source file.
#include "source.h"
Test::Test()
:array_length{0} //Typo of array{0}
{
}
These are the problem messages.
[enter image description here][1]
[1]: https://i.stack.imgur.com/IQ2Mk.png
This is the CMake file.
cmake_minimum_required(VERSION 3.0.0)
project(temp VERSION 0.1.0)
include(CTest)
enable_testing()
add_executable(temp main.cpp)
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
include(CPack)
Finally, these are what the compiler is complaining about when I try to build the project.
[main] Building folder: temp
[build] Starting build
[proc] Executing command: /usr/local/bin/cmake --build /Users/USERNAME/Desktop/temp/build --config Debug --target all -j 14 --
[build] [1/2 50% :: 0.066] Building CXX object CMakeFiles/temp.dir/main.cpp.o
[build] FAILED: CMakeFiles/temp.dir/main.cpp.o
[build] /usr/bin/clang++ -g -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.3.sdk -MD -MT CMakeFiles/temp.dir/main.cpp.o -MF CMakeFiles/temp.dir/main.cpp.o.d -o CMakeFiles/temp.dir/main.cpp.o -c ../main.cpp
[build] In file included from ../main.cpp:1:
[build] ../source.h:8:22: error: function definition does not declare parameters
[build] static const int array_length{2};
[build] ^
[build] ../source.h:9:18: error: use of undeclared identifier 'array_length'
[build] double array[array_length];
[build] ^
[build] 2 errors generated.
[build] ninja: build stopped: subcommand failed.
[build] Build finished with exit code 1
I am using macOS 12.0 beta, with VS Code 1.60.2, clang 13.0.0, CMake 3.20.2.
Please let me know if you see any wrong or have any suggestions.
This cannot work:
Test::Test()
:array_length{0}
You cannot set a const static data member in your constructor. A static value has the same value accross all object instances. But as it is also const no instance is allowed to change the value.
Since array_length is static const you have to initialize it like this:
source.h
#ifndef SOUECE_H
#define SOURCE_H
class Test
{
public:
Test();
static const int array_length = 2;
//static const int array_length{2}; this will also work just note that we cannot use constructor initializer list to initialize static data members
double array[array_length];
};
#endif
source.cpp
#include "source.h"
Test::Test()//we cannot use constructor initializer list to initialize array_length
{
}
Note that static const int array_length{2}; will also work but the thing is that in the constructor we cannot use constructor initializer list to initialize static data member.
EDIT:
If you decide to use static const int array_length{2}; then make sure that you have C++11(or later) enabled in your CMakeLists.txt. For this you can add
set (CMAKE_CXX_STANDARD 11)
to your CMakeLists.txt.
Alternatively, you could instead add
target_compile_features(targetname PUBLIC cxx_std_11)
in your CMakeLists.txt. In your case replace targetname with temp since that is the targetname that you have. Check this out for more how to active C++11 in CMake .
Related
When I compile this code in C it runs perfectly but when I try to compile it in C++ it sends an error which I'll add below. I've tried declaring the function with every variable type I could think of which didn't change anything. I also searched online but found nothing that helped.
Code:
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"
void gpio_callback() {
printf("GPIO RISE\n");
}
int main() {
stdio_init_all();
printf("Hello GPIO IRQ\n");
gpio_set_irq_enabled_with_callback(2, GPIO_IRQ_EDGE_RISE, true, &gpio_callback);
// Wait forever
while (1);
return 0;
}
My CMakeFile.txt for C++:
cmake_minimum_required(VERSION 3.19)
include(pico_sdk_import.cmake)
project(hello_gpio_irq)
pico_sdk_init()
add_executable(hello_gpio_irq hello_gpio_irq.cpp)
pico_enable_stdio_usb(hello_gpio_irq 1)
pico_enable_stdio_uart(hello_gpio_irq 0)
# pull in common dependencies
target_link_libraries(hello_gpio_irq pico_stdlib)
# create map/bin/hex file etc.
pico_add_extra_outputs(hello_gpio_irq)
My CmakeLists.txt for C:
cmake_minimum_required(VERSION 3.19)
include(pico_sdk_import.cmake)
project(hello_gpio_irq)
pico_sdk_init()
add_executable(hello_gpio_irq hello_gpio_irq.c)
pico_enable_stdio_usb(hello_gpio_irq 1)
pico_enable_stdio_uart(hello_gpio_irq 0)
# pull in common dependencies
target_link_libraries(hello_gpio_irq pico_stdlib)
# create map/bin/hex file etc.
pico_add_extra_outputs(hello_gpio_irq)
Compiler output for C++:
[main] Building folder: hello_gpio_irq
[build] Starting build
[proc] Executing command: /usr/bin/cmake --build /home/taylor/Documents/Programs/Pi-Pico/hello_gpio_irq/build --config Debug --target all --
[build] [2/8 12% :: 0.025] Performing build step for 'ELF2UF2Build'
[build] ninja: no work to do.
[build] [3/8 25% :: 0.057] Performing build step for 'PioasmBuild'
[build] ninja: no work to do.
[build] [4/8 37% :: 0.071] No install step for 'ELF2UF2Build'
[build] [5/8 50% :: 0.110] No install step for 'PioasmBuild'
[build] [6/8 62% :: 0.149] Completed 'ELF2UF2Build'
[build] [7/8 75% :: 0.155] Completed 'PioasmBuild'
[build] [7/8 87% :: 0.267] Building CXX object CMakeFiles/hello_gpio_irq.dir/hello_gpio_irq.cpp.obj
[build] FAILED: CMakeFiles/hello_gpio_irq.dir/hello_gpio_irq.cpp.obj
[build] /usr/bin/arm-none-eabi-g++ -DCFG_TUSB_DEBUG=1 -DCFG_TUSB_MCU=OPT_MCU_RP2040 -DCFG_TUSB_OS=OPT_OS_PICO -DLIB_PICO_BIT_OPS=1 -DLIB_PICO_BIT_OPS_PICO=1 -DLIB_PICO_DIVIDER=1 -DLIB_PICO_DIVIDER_HARDWARE=1 -DLIB_PICO_DOUBLE=1 -DLIB_PICO_DOUBLE_PICO=1 -DLIB_PICO_FIX_RP2040_USB_DEVICE_ENUMERATION=1 -DLIB_PICO_FLOAT=1 -DLIB_PICO_FLOAT_PICO=1 -DLIB_PICO_INT64_OPS=1 -DLIB_PICO_INT64_OPS_PICO=1 -DLIB_PICO_MALLOC=1 -DLIB_PICO_MEM_OPS=1 -DLIB_PICO_MEM_OPS_PICO=1 -DLIB_PICO_PLATFORM=1 -DLIB_PICO_PRINTF=1 -DLIB_PICO_PRINTF_PICO=1 -DLIB_PICO_RUNTIME=1 -DLIB_PICO_STANDARD_LINK=1 -DLIB_PICO_STDIO=1 -DLIB_PICO_STDIO_USB=1 -DLIB_PICO_STDLIB=1 -DLIB_PICO_SYNC=1 -DLIB_PICO_SYNC_CORE=1 -DLIB_PICO_SYNC_CRITICAL_SECTION=1 -DLIB_PICO_SYNC_MUTEX=1 -DLIB_PICO_SYNC_SEM=1 -DLIB_PICO_TIME=1 -DLIB_PICO_UNIQUE_ID=1 -DLIB_PICO_UTIL=1 -DPICO_BOARD=\"pico\" -DPICO_BUILD=1 -DPICO_CMAKE_BUILD_TYPE=\"Debug\" -DPICO_COPY_TO_RAM=0 -DPICO_CXX_ENABLE_EXCEPTIONS=0 -DPICO_NO_FLASH=0 -DPICO_NO_HARDWARE=0 -DPICO_ON_DEVICE=1 -DPICO_TARGET_NAME=\"hello_gpio_irq\" -DPICO_USE_BLOCKED_RAM=0 -I/home/taylor/pico/pico-sdk/src/common/pico_stdlib/include -I/home/taylor/pico/pico-sdk/src/rp2_common/hardware_gpio/include -I/home/taylor/pico/pico-sdk/src/common/pico_base/include -I/home/taylor/Documents/Programs/Pi-Pico/hello_gpio_irq/build/generated/pico_base -I/home/taylor/pico/pico-sdk/src/boards/include -I/home/taylor/pico/pico-sdk/src/rp2_common/pico_platform/include -I/home/taylor/pico/pico-sdk/src/rp2040/hardware_regs/include -I/home/taylor/pico/pico-sdk/src/rp2_common/hardware_base/include -I/home/taylor/pico/pico-sdk/src/rp2040/hardware_structs/include -I/home/taylor/pico/pico-sdk/src/rp2_common/hardware_claim/include -I/home/taylor/pico/pico-sdk/src/rp2_common/hardware_sync/include -I/home/taylor/pico/pico-sdk/src/rp2_common/hardware_irq/include -I/home/taylor/pico/pico-sdk/src/common/pico_sync/include -I/home/taylor/pico/pico-sdk/src/common/pico_time/include -I/home/taylor/pico/pico-sdk/src/rp2_common/hardware_timer/include -I/home/taylor/pico/pico-sdk/src/common/pico_util/include -I/home/taylor/pico/pico-sdk/src/rp2_common/hardware_uart/include -I/home/taylor/pico/pico-sdk/src/rp2_common/hardware_divider/include -I/home/taylor/pico/pico-sdk/src/rp2_common/pico_runtime/include -I/home/taylor/pico/pico-sdk/src/rp2_common/hardware_clocks/include -I/home/taylor/pico/pico-sdk/src/rp2_common/hardware_resets/include -I/home/taylor/pico/pico-sdk/src/rp2_common/hardware_pll/include -I/home/taylor/pico/pico-sdk/src/rp2_common/hardware_vreg/include -I/home/taylor/pico/pico-sdk/src/rp2_common/hardware_watchdog/include -I/home/taylor/pico/pico-sdk/src/rp2_common/hardware_xosc/include -I/home/taylor/pico/pico-sdk/src/rp2_common/pico_printf/include -I/home/taylor/pico/pico-sdk/src/rp2_common/pico_bootrom/include -I/home/taylor/pico/pico-sdk/src/common/pico_bit_ops/include -I/home/taylor/pico/pico-sdk/src/common/pico_divider/include -I/home/taylor/pico/pico-sdk/src/rp2_common/pico_double/include -I/home/taylor/pico/pico-sdk/src/rp2_common/pico_int64_ops/include -I/home/taylor/pico/pico-sdk/src/rp2_common/pico_float/include -I/home/taylor/pico/pico-sdk/src/rp2_common/pico_malloc/include -I/home/taylor/pico/pico-sdk/src/rp2_common/boot_stage2/include -I/home/taylor/pico/pico-sdk/src/common/pico_binary_info/include -I/home/taylor/pico/pico-sdk/src/rp2_common/pico_stdio/include -I/home/taylor/pico/pico-sdk/src/rp2_common/pico_stdio_usb/include -I/home/taylor/pico/pico-sdk/lib/tinyusb/src -I/home/taylor/pico/pico-sdk/lib/tinyusb/src/common -I/home/taylor/pico/pico-sdk/lib/tinyusb/hw -I/home/taylor/pico/pico-sdk/src/rp2_common/pico_fix/rp2040_usb_device_enumeration/include -I/home/taylor/pico/pico-sdk/src/rp2_common/pico_unique_id/include -I/home/taylor/pico/pico-sdk/src/rp2_common/hardware_flash/include -I/home/taylor/pico/pico-sdk/src/common/pico_usb_reset_interface/include -mcpu=cortex-m0plus -mthumb -Og -g -ffunction-sections -fdata-sections -fno-exceptions -fno-unwind-tables -fno-rtti -fno-use-cxa-atexit -MD -MT CMakeFiles/hello_gpio_irq.dir/hello_gpio_irq.cpp.obj -MF CMakeFiles/hello_gpio_irq.dir/hello_gpio_irq.cpp.obj.d -o CMakeFiles/hello_gpio_irq.dir/hello_gpio_irq.cpp.obj -c /home/taylor/Documents/Programs/Pi-Pico/hello_gpio_irq/hello_gpio_irq.cpp
[build] /home/taylor/Documents/Programs/Pi-Pico/hello_gpio_irq/hello_gpio_irq.cpp: In function 'int main()':
[build] /home/taylor/Documents/Programs/Pi-Pico/hello_gpio_irq/hello_gpio_irq.cpp:13:69: error: invalid conversion from 'void (*)()' to 'gpio_irq_callback_t' {aka 'void (*)(unsigned int, long unsigned int)'} [-fpermissive]
[build] 13 | gpio_set_irq_enabled_with_callback(2, GPIO_IRQ_EDGE_RISE, true, &gpio_callback);
[build] | ^~~~~~~~~~~~~~
[build] | |
[build] | void (*)()
[build] In file included from /home/taylor/pico/pico-sdk/src/common/pico_stdlib/include/pico/stdlib.h:13,
[build] from /home/taylor/Documents/Programs/Pi-Pico/hello_gpio_irq/hello_gpio_irq.cpp:2:
[build] /home/taylor/pico/pico-sdk/src/rp2_common/hardware_gpio/include/hardware/gpio.h:440:107: note: initializing argument 4 of 'void gpio_set_irq_enabled_with_callback(uint, uint32_t, bool, gpio_irq_callback_t)'
[build] 440 | void gpio_set_irq_enabled_with_callback(uint gpio, uint32_t event_mask, bool enabled, gpio_irq_callback_t callback);
[build] | ~~~~~~~~~~~~~~~~~~~~^~~~~~~~
[build] ninja: build stopped: subcommand failed.
[proc] The command: /usr/bin/cmake --build /home/taylor/Documents/Programs/Pi-Pico/hello_gpio_irq/build --config Debug --target all -- exited with code: 1 and signal: null
[build] Build finished with exit code 1
void gpio_set_irq_enabled_with_callback (uint gpio,
uint32_t event_mask,
bool enabled,
gpio_irq_callback_t callback)
expects a gpio_irq_callback_t for the final parameter, and gpio_irq_callback_t looks like
typedef void(* gpio_irq_callback_t) (uint gpio, uint32_t event_mask)
so gpio_set_irq_enabled_with_callback expects
void gpio_callback() {
printf("GPIO RISE\n");
}
to be
void gpio_callback(uint /*gpio*/, uint32_t /*event_mask*/) {
printf("GPIO RISE\n");
}
You can uncomment the parameter names when you choose to use them. Until you do, you'll likely get unused parameter warnings.
This only looks like it works in C because C will compile it. You'll probably get a warning if you turn them up loud enough because there are no guarantees that it will behave correctly at runtime. Depending on the calling convention the results could be catastrophic. For example, if the callee is responsible for popping the parameters off the stack, void () doesn't expect parameters and won't pop anything. The two parameters the caller pushed onto the stack will sit there, throwing the stack off and screwing everything up in unpredictable ways. C++ is much more anally retentive about matching types and rejects the function outright, so you get a compiler error instead of a warning or the program freaking out at runtime.
Do NOT attempt to fix this with a cast. You'll likely only trade the compiler error in for unusual behaviour at runtime.
I'm setting up an IRQ on a Raspberry Pi Pico in C++ but when I compile my code it tells me the callback function is "Not declared in this scope". I've been beating my head against the wall for hours because the function is declared and it's public.
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/gpio.h"
uint64_t time_between_triggers;
uint16_t times_triggered;
void shaft_speed_init(uint8_t _gpio_number, uint8_t _precision, uint8_t _counts_per_turn){
gpio_set_irq_enabled_with_callback(2, GPIO_IRQ_EDGE_RISE, true, &_shaft_speed_gpio_callback);
}
void _shaft_speed_gpio_callback(uint16_t _gpio, uint32_t _event_mask) {
uint64_t trigger_time;
static uint64_t prev_trigger_time;
trigger_time = to_us_since_boot(get_absolute_time());
time_between_triggers = time_between_triggers + (trigger_time - prev_trigger_time);
prev_trigger_time = trigger_time;
times_triggered++;
}
[main] Building folder: variable_rate_planter
[build] Starting build
[proc] Executing command: /usr/bin/cmake --build /home/taylor/Documents/Programs/Pi-Pico/variable_rate_planter/build --config Debug --target all --
[build] [2/8 12% :: 0.017] Performing build step for 'PioasmBuild'
[build] ninja: no work to do.
[build] [3/8 25% :: 0.026] Performing build step for 'ELF2UF2Build'
[build] ninja: no work to do.
[build] [4/8 37% :: 0.043] No install step for 'PioasmBuild'
[build] [5/8 50% :: 0.052] No install step for 'ELF2UF2Build'
[build] [6/8 62% :: 0.083] Completed 'PioasmBuild'
[build] [6/8 75% :: 0.095] Completed 'ELF2UF2Build'
[build] [7/8 87% :: 0.201] Building CXX object CMakeFiles/vrp.dir/main.cpp.obj
[build] FAILED: CMakeFiles/vrp.dir/main.cpp.obj
[build] /usr/bin/arm-none-eabi-g++ -DCFG_TUSB_DEBUG=1 -DCFG_TUSB_MCU=OPT_MCU_RP2040 -DCFG_TUSB_OS=OPT_OS_PICO -DLIB_PICO_BIT_OPS=1 -DLIB_PICO_BIT_OPS_PICO=1 -DLIB_PICO_DIVIDER=1 -DLIB_PICO_DIVIDER_HARDWARE=1 -DLIB_PICO_DOUBLE=1 -DLIB_PICO_DOUBLE_PICO=1 -DLIB_PICO_FIX_RP2040_USB_DEVICE_ENUMERATION=1 -DLIB_PICO_FLOAT=1 -DLIB_PICO_FLOAT_PICO=1 -DLIB_PICO_INT64_OPS=1 -DLIB_PICO_INT64_OPS_PICO=1 -DLIB_PICO_MALLOC=1 -DLIB_PICO_MEM_OPS=1 -DLIB_PICO_MEM_OPS_PICO=1 -DLIB_PICO_PLATFORM=1 -DLIB_PICO_PRINTF=1 -DLIB_PICO_PRINTF_PICO=1 -DLIB_PICO_RUNTIME=1 -DLIB_PICO_STANDARD_LINK=1 -DLIB_PICO_STDIO=1 -DLIB_PICO_STDIO_USB=1 -DLIB_PICO_STDLIB=1 -DLIB_PICO_SYNC=1 -DLIB_PICO_SYNC_CORE=1 -DLIB_PICO_SYNC_CRITICAL_SECTION=1 -DLIB_PICO_SYNC_MUTEX=1 -DLIB_PICO_SYNC_SEM=1 -DLIB_PICO_TIME=1 -DLIB_PICO_UNIQUE_ID=1 -DLIB_PICO_UTIL=1 -DPICO_BOARD=\"pico\" -DPICO_BUILD=1 -DPICO_CMAKE_BUILD_TYPE=\"Debug\" -DPICO_COPY_TO_RAM=0 -DPICO_CXX_ENABLE_EXCEPTIONS=0 -DPICO_NO_FLASH=0 -DPICO_NO_HARDWARE=0 -DPICO_ON_DEVICE=1 -DPICO_TARGET_NAME=\"vrp\" -DPICO_USE_BLOCKED_RAM=0 -I/home/taylor/pico/pico-sdk/src/common/pico_stdlib/include -I/home/taylor/pico/pico-sdk/src/rp2_common/hardware_gpio/include -I/home/taylor/pico/pico-sdk/src/common/pico_base/include -I/home/taylor/Documents/Programs/Pi-Pico/variable_rate_planter/build/generated/pico_base -I/home/taylor/pico/pico-sdk/src/boards/include -I/home/taylor/pico/pico-sdk/src/rp2_common/pico_platform/include -I/home/taylor/pico/pico-sdk/src/rp2040/hardware_regs/include -I/home/taylor/pico/pico-sdk/src/rp2_common/hardware_base/include -I/home/taylor/pico/pico-sdk/src/rp2040/hardware_structs/include -I/home/taylor/pico/pico-sdk/src/rp2_common/hardware_claim/include -I/home/taylor/pico/pico-sdk/src/rp2_common/hardware_sync/include -I/home/taylor/pico/pico-sdk/src/rp2_common/hardware_irq/include -I/home/taylor/pico/pico-sdk/src/common/pico_sync/include -I/home/taylor/pico/pico-sdk/src/common/pico_time/include -I/home/taylor/pico/pico-sdk/src/rp2_common/hardware_timer/include -I/home/taylor/pico/pico-sdk/src/common/pico_util/include -I/home/taylor/pico/pico-sdk/src/rp2_common/hardware_uart/include -I/home/taylor/pico/pico-sdk/src/rp2_common/hardware_divider/include -I/home/taylor/pico/pico-sdk/src/rp2_common/pico_runtime/include -I/home/taylor/pico/pico-sdk/src/rp2_common/hardware_clocks/include -I/home/taylor/pico/pico-sdk/src/rp2_common/hardware_resets/include -I/home/taylor/pico/pico-sdk/src/rp2_common/hardware_pll/include -I/home/taylor/pico/pico-sdk/src/rp2_common/hardware_vreg/include -I/home/taylor/pico/pico-sdk/src/rp2_common/hardware_watchdog/include -I/home/taylor/pico/pico-sdk/src/rp2_common/hardware_xosc/include -I/home/taylor/pico/pico-sdk/src/rp2_common/pico_printf/include -I/home/taylor/pico/pico-sdk/src/rp2_common/pico_bootrom/include -I/home/taylor/pico/pico-sdk/src/common/pico_bit_ops/include -I/home/taylor/pico/pico-sdk/src/common/pico_divider/include -I/home/taylor/pico/pico-sdk/src/rp2_common/pico_double/include -I/home/taylor/pico/pico-sdk/src/rp2_common/pico_int64_ops/include -I/home/taylor/pico/pico-sdk/src/rp2_common/pico_float/include -I/home/taylor/pico/pico-sdk/src/rp2_common/pico_malloc/include -I/home/taylor/pico/pico-sdk/src/rp2_common/boot_stage2/include -I/home/taylor/pico/pico-sdk/src/common/pico_binary_info/include -I/home/taylor/pico/pico-sdk/src/rp2_common/pico_stdio/include -I/home/taylor/pico/pico-sdk/src/rp2_common/pico_stdio_usb/include -I/home/taylor/pico/pico-sdk/lib/tinyusb/src -I/home/taylor/pico/pico-sdk/lib/tinyusb/src/common -I/home/taylor/pico/pico-sdk/lib/tinyusb/hw -I/home/taylor/pico/pico-sdk/src/rp2_common/pico_fix/rp2040_usb_device_enumeration/include -I/home/taylor/pico/pico-sdk/src/rp2_common/pico_unique_id/include -I/home/taylor/pico/pico-sdk/src/rp2_common/hardware_flash/include -I/home/taylor/pico/pico-sdk/src/common/pico_usb_reset_interface/include -mcpu=cortex-m0plus -mthumb -Og -g -ffunction-sections -fdata-sections -fno-exceptions -fno-unwind-tables -fno-rtti -fno-use-cxa-atexit -MD -MT CMakeFiles/vrp.dir/main.cpp.obj -MF CMakeFiles/vrp.dir/main.cpp.obj.d -o CMakeFiles/vrp.dir/main.cpp.obj -c /home/taylor/Documents/Programs/Pi-Pico/variable_rate_planter/main.cpp
[build] In file included from /home/taylor/Documents/Programs/Pi-Pico/variable_rate_planter/main.cpp:4:
[build] /home/taylor/Documents/Programs/Pi-Pico/variable_rate_planter/shaft_speed.h: In function 'void shaft_speed_init(uint8_t, uint8_t, uint8_t)':
[build] /home/taylor/Documents/Programs/Pi-Pico/variable_rate_planter/shaft_speed.h:9:70: error: '_shaft_speed_gpio_callback' was not declared in this scope
[build] 9 | gpio_set_irq_enabled_with_callback(2, GPIO_IRQ_EDGE_RISE, true, &_shaft_speed_gpio_callback);
[build] | ^~~~~~~~~~~~~~~~~~~~~~~~~~
[build] ninja: build stopped: subcommand failed.
[proc] The command: /usr/bin/cmake --build /home/taylor/Documents/Programs/Pi-Pico/variable_rate_planter/build --config Debug --target all -- exited with code: 1 and signal: null
[build] Build finished with exit code 1
Your function _shaft_speed_gpio_callback appears to be defined after the point in the code where it's used. You need to add a function declaration (a.k.a "prototype") so the compiler knows what the name refers to:
// Add this
void _shaft_speed_gpio_callback(uint16_t _gpio, uint32_t _event_mask);
// The rest of your code as provided
void shaft_speed_init(uint8_t _gpio_number, uint8_t _precision, uint8_t _counts_per_turn){
gpio_set_irq_enabled_with_callback(2, GPIO_IRQ_EDGE_RISE, true, &_shaft_speed_gpio_callback);
}
void _shaft_speed_gpio_callback(uint16_t _gpio, uint32_t _event_mask) {
// ...
}
Ok, I have this strange bug, or behavior I don't understand. If I use -static-libstdc++ link flag in my project, LLDB fails to show underlying type of a pointer. So here is small example. I have the very basic test executable, with only one main.cpp file:
// main.cpp
#include <memory>
class TestBase
{
public:
TestBase() = default;
virtual ~TestBase() = default;
int m_baseInt = 10;
};
class TestDerived : public TestBase
{
public:
TestDerived() = default;
virtual ~TestDerived() override = default;
int m_derivedInt = 20;
};
int main(int,char*[])
{
std::unique_ptr<TestBase> regularBase = std::make_unique<TestBase>();
std::unique_ptr<TestBase> hiddentBase = std::make_unique<TestDerived>();
TestBase*volatile base = hiddentBase.get();
volatile int breakpoint = 10;
++breakpoint;
}
and one CMake file to build it
# CMakeLists.txt
cmake_minimum_required(VERSION 3.19.0 FATAL_ERROR)
project(quick-test VERSION 0.1.0 LANGUAGES CXX C)
add_executable(test-exe "main.cpp")
For ide I use vscode with CodeLLDB module, and so if you look at 'base' variable it will show TestDerived class (as it should):
But with only one chage, by adding -static-libstdc++ link option to my test executable
# CMakeLists.txt
cmake_minimum_required(VERSION 3.19.0 FATAL_ERROR)
project(quick-test VERSION 0.1.0 LANGUAGES CXX C)
add_executable(test-exe "main.cpp")
target_link_options(test-exe PRIVATE -static-libstdc++)
now lldb is incapable to deduce underlying type of a 'base' pointer:
For compilation I used clang 14.0.0 and gcc 11.2.0, but it didn't make any difference.
Why does linking statically c++ std lib causes this, and is there any solution for this accept removing this flag?
This question already has answers here:
Undefined reference error for static constexpr member
(2 answers)
Closed 5 years ago.
#include <iostream>
#include <vector>
#include <memory>
class Node{
public:
static constexpr int data_size = sizeof(int);
};
class View{
public:
View(int size){
}
};
class Header: public Node{
public:
void foo(){
std::shared_ptr<View> v = std::make_shared<View>(data_size);
}
void bar(){
std::shared_ptr<View> v(new View(data_size));
}
View bar1(){
return View(data_size);
}
void bar2(){
View *v = new View(data_size);
}
int bar3(){
return data_size;
}
};
int main() {
Header *h = new Header();
// This 1 lines below will produce the error
h->foo();
// These 4 lines are ok
h->bar();
h->bar1();
h->bar2();
h->bar3();
return 0;
}
When call foo() , error below will occur :
/Applications/CLion.app/Contents/bin/cmake/bin/cmake --build /Users/everettjf/code/cpptest/cmake-build-debug --target all -- -j 8
Scanning dependencies of target cpptest
[ 50%] Building CXX object CMakeFiles/cpptest.dir/main.cpp.o
[100%] Linking CXX executable cpptest
Undefined symbols for architecture x86_64:
"Node::data_size", referenced from:
Header::foo() in main.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [cpptest] Error 1
make[1]: *** [CMakeFiles/cpptest.dir/all] Error 2
make: *** [all] Error 2
When I use new to initialize the shared_ptr ,it is ok.But when I use make_shared, the link error occurs.
Why std::make_shared different with new when construct with static constexpr member ?
My environment is macOS with Clion, CMakeList.txt is :
cmake_minimum_required(VERSION 3.6)
project(cpptest)
set(CMAKE_CXX_STANDARD 11)
set(SOURCE_FILES main.cpp)
add_executable(cpptest ${SOURCE_FILES})
Why new is working..
std::shared_ptr<View> v(new View(data_size));
In the above code (my guess is) the compiler substitutes data_size with the value itself. So it compiles and runs fine.
Why std::make_shared<>() fails ..
std::shared_ptr<View> v = std::make_shared<View>(data_size);
std::make_shared does something called perfect forwarding. And in the above case it needs to know the address of Node::data_size. Since you have not defined it anywhere, you linker can't find the symbols and throws the error.
To solve this problem, define the symbol Node::data_size in your code.
I am trying to compile simple gmock example on my ubuntu vmware(16.04 LTS)
and getting below error while doing "make"
I have below files -
"test.h"
class CBasicMath
{
public:
CBasicMath(){}
virtual ~CBasicMath() {}
virtual int Addition(int x, int y);
virtual int Multiply(int x, int y);
virtual int Divide(int x, int y);
};
"test.cpp"
#include "test.h"
int CBasicMath::Addition(int x, int y)
{
return (x + y);
}
int CBasicMath::Multiply(int x, int y)
{
return (x * y);
}
int CBasicMath::Divide(int x, int y)
{
return (x / y);
}
"mocktest.h"
#include "gmock/gmock.h"
#include "test.cpp"
class MockBasicTest : public CBasicMath {
public:
MOCK_METHOD2(Addition, int(int x, int y));
MOCK_METHOD2(Multiply, int(int x, int y));
MOCK_METHOD2(Divide, int(int x, int y));
};
"main.cpp"
#include "mocktest.h"
#include "gtest/gtest.h"
#include "gmock/gmock.h"
TEST(BasicMathTest, testAddition) {
MockBasicTest basictest;
EXPECT_CALL(basictest, Addition(2,3)).Times(0);
// EXPECT_EQ(0, basictest.Addition(2,3));
/*
.Times(5);
EXPECT_EQ(0,basictest.Addition(2,3));
EXPECT_EQ(0,basictest.Addition(2,3));
EXPECT_EQ(0,basictest.Addition(2,3));
EXPECT_EQ(0,basictest.Addition(2,3));
EXPECT_EQ(0,basictest.Addition(2,3));
*/
}
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
"CMakeLists.txt"
cmake_minimum_required(VERSION 2.6)
# Locate GTest
find_package(GTest REQUIRED)
include_directories(${GTEST_INCLUDE_DIRS})
# Link runTests with what we want to test and the GTest and pthread library
add_executable(runTests main.cpp)
target_link_libraries(runTests -lgtest -lgmock -lpthread)
These are the steps I followed for compilation -
ajay#ubuntu:~/Desktop/for_gtest/ajay/gtest/ajay/demo/gmock/simple_demo$ cmake CMakeLists.txt
-- Configuring done
-- Generating done
-- Build files have been written to: /home/ajay/Desktop/for_gtest/ajay/gtest/ajay/demo/gmock/simple_demo
ajay#ubuntu:~/Desktop/for_gtest/ajay/gtest/ajay/demo/gmock/simple_demo$
and after that When I did make I am facing the issue
ajay#ubuntu:~/Desktop/for_gtest/ajay/gtest/ajay/demo/gmock/simple_demo$ make
Scanning dependencies of target runTests
make[2]: Warning: File 'main.cpp' has modification time 84978 s in the future
[ 50%] Building CXX object CMakeFiles/runTests.dir/main.cpp.o
[100%] Linking CXX executable runTests
/usr/bin/ld: cannot find -lgmock
collect2: error: ld returned 1 exit status
CMakeFiles/runTests.dir/build.make:94: recipe for target 'runTests' failed
make[2]: *** [runTests] Error 1
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/runTests.dir/all' failed
make[1]: *** [CMakeFiles/runTests.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2
ajay#ubuntu:~/Desktop/for_gtest/ajay/gtest/ajay/demo/gmock/simple_demo$
I don't know why this "/usr/bin/ld: cannot find -lgmock" issue is coming even though I have installed gmock successfully.
I am able to run gtest programs but when I am adding gmock I am getting this issue.
Please help me to resolve.
Let me know for more info.
Lookup the documentation for taget_link_libraries. Check the comments in FindGtest.cmake
You should not specify libraries them with -l instead use the variables from find_package e.g. ${GTEST_LIBRARIES}
You haven't done find_package for GMOCK so there are no variables defined for GMOCK. As this is not a standard CMake module, write your own or take one from the Internet
BUT, the Google test documentation recommends not use the installed libraries from the system, but to build them yourself inside your Project.There are several examples on the internet how to add gtest/gmock as ExternalProject to your cmake project.