From 72451b3e0d39133946ea7ef78f8effefd978ab1f Mon Sep 17 00:00:00 2001 From: Thiago Alves Date: Tue, 14 Apr 2026 23:50:01 -0400 Subject: [PATCH] fix: guard exception headers and throw statements for AVR targets AVR doesn't support , , or exceptions. Guard these includes with #ifndef __AVR__ and replace throw statements with infinite loops (halt) on AVR targets. Affects iec_array.hpp, iec_located.hpp, and iec_pointer.hpp. Non-AVR targets are unchanged -- full exception support preserved. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/runtime/include/iec_array.hpp | 18 ++++++++++++++++++ src/runtime/include/iec_located.hpp | 10 ++++++++++ src/runtime/include/iec_pointer.hpp | 28 ++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+) diff --git a/src/runtime/include/iec_array.hpp b/src/runtime/include/iec_array.hpp index ddee3cb..261198a 100644 --- a/src/runtime/include/iec_array.hpp +++ b/src/runtime/include/iec_array.hpp @@ -14,7 +14,9 @@ #include #include +#ifndef __AVR__ #include +#endif #include "iec_var.hpp" namespace strucpp { @@ -77,14 +79,22 @@ class IEC_ARRAY_1D { // Bounds-checked access - throws std::out_of_range on invalid index var_type& at(int64_t index) { if (!Bounds::in_bounds(index)) { +#ifdef __AVR__ + for(;;); // halt on bounds error (no exceptions on AVR) +#else throw std::out_of_range("Array index out of bounds"); +#endif } return data_[to_internal_index(index)]; } const var_type& at(int64_t index) const { if (!Bounds::in_bounds(index)) { +#ifdef __AVR__ + for(;;); // halt on bounds error (no exceptions on AVR) +#else throw std::out_of_range("Array index out of bounds"); +#endif } return data_[to_internal_index(index)]; } @@ -140,14 +150,22 @@ class IEC_ARRAY_2D { // Bounds-checked access - throws std::out_of_range on invalid index var_type& at(int64_t i, int64_t j) { if (!Bounds1::in_bounds(i) || !Bounds2::in_bounds(j)) { +#ifdef __AVR__ + for(;;); // halt on bounds error (no exceptions on AVR) +#else throw std::out_of_range("Array index out of bounds"); +#endif } return data_[to_linear_index(i, j)]; } const var_type& at(int64_t i, int64_t j) const { if (!Bounds1::in_bounds(i) || !Bounds2::in_bounds(j)) { +#ifdef __AVR__ + for(;;); // halt on bounds error (no exceptions on AVR) +#else throw std::out_of_range("Array index out of bounds"); +#endif } return data_[to_linear_index(i, j)]; } diff --git a/src/runtime/include/iec_located.hpp b/src/runtime/include/iec_located.hpp index 842d628..177a869 100644 --- a/src/runtime/include/iec_located.hpp +++ b/src/runtime/include/iec_located.hpp @@ -16,7 +16,9 @@ #pragma once #include +#ifndef __AVR__ #include +#endif namespace strucpp { @@ -137,7 +139,11 @@ inline LocatedArea parse_area(char c) { case 'I': case 'i': return LocatedArea::Input; case 'Q': case 'q': return LocatedArea::Output; case 'M': case 'm': return LocatedArea::Memory; +#ifdef __AVR__ + default: for(;;); +#else default: throw std::invalid_argument("Invalid area character"); +#endif } } @@ -154,7 +160,11 @@ inline LocatedSize parse_size(char c) { case 'W': case 'w': return LocatedSize::Word; case 'D': case 'd': return LocatedSize::DWord; case 'L': case 'l': return LocatedSize::LWord; +#ifdef __AVR__ + default: for(;;); +#else default: throw std::invalid_argument("Invalid size character"); +#endif } } diff --git a/src/runtime/include/iec_pointer.hpp b/src/runtime/include/iec_pointer.hpp index 879c430..b1bcf02 100644 --- a/src/runtime/include/iec_pointer.hpp +++ b/src/runtime/include/iec_pointer.hpp @@ -46,8 +46,10 @@ #pragma once #include +#ifndef __AVR__ #include #include +#endif #include "iec_var.hpp" namespace strucpp { @@ -56,6 +58,7 @@ namespace strucpp { // Null Reference Exception // ============================================================================= +#ifndef __AVR__ /** * Exception thrown when dereferencing a NULL reference. * The runtime catches this and stops execution of the affected POU. @@ -71,6 +74,7 @@ class NullReferenceException : public std::runtime_error { explicit NullReferenceException(const std::string& context) : std::runtime_error("Null reference dereference in " + context) {} }; +#endif // ============================================================================= // IEC NULL Constant @@ -147,14 +151,22 @@ class IEC_REF_TO { */ IECVar& deref() { if (ptr_ == nullptr) { +#ifdef __AVR__ + for(;;); +#else throw NullReferenceException(); +#endif } return *ptr_; } const IECVar& deref() const { if (ptr_ == nullptr) { +#ifdef __AVR__ + for(;;); +#else throw NullReferenceException(); +#endif } return *ptr_; } @@ -164,14 +176,22 @@ class IEC_REF_TO { */ IECVar& deref(const char* context) { if (ptr_ == nullptr) { +#ifdef __AVR__ + for(;;); +#else throw NullReferenceException(context); +#endif } return *ptr_; } const IECVar& deref(const char* context) const { if (ptr_ == nullptr) { +#ifdef __AVR__ + for(;;); +#else throw NullReferenceException(context); +#endif } return *ptr_; } @@ -213,14 +233,22 @@ class IEC_REF_TO { */ pointer_type operator->() { if (ptr_ == nullptr) { +#ifdef __AVR__ + for(;;); +#else throw NullReferenceException(); +#endif } return ptr_; } const pointer_type operator->() const { if (ptr_ == nullptr) { +#ifdef __AVR__ + for(;;); +#else throw NullReferenceException(); +#endif } return ptr_; }