static const int PORT_MAX_CHANNELS = 16;
float voltages[PORT_MAX_CHANNELS] = {};
So clearly voltages[16] is illegal. But the comments in setChannels imply that 16 is a legal value there (calling setChannels(16)). Not sure what’s going on.
In a way, the compiler warning is correct. The method Port::setChannels() contains
for (int c = channels; c < this->channels; c++) {
voltages[c] = 0.f;
}
which buffer-overruns if this->channels > 16. However, this should only happen if a plugin developer sets >16 channels which would be incorrect.
Port methods purposely have no input sanitation because it prioritizes speed. Any extra instructions would make a measurable difference in performance.
I’ll look into a way to suppress this error, but in the meantime, just ignore it.
have you considered a channels = std::clamp(channels, 0, WHATEVER_THE_MAX_POLY_DEF_IS) at the top of the method body? Or alternately c < this->channels && c < MAX_POLY_DEF in the loop should do the same.
ahh i guess those both fail your extra instruction test though. Is setChannels called frequently in peoples code? if so, wouldn’t a top level bailout like if (channels == this->channels) return also help? Anyway peanut gallery, free comment, etc…
GCC reports an error because the function parameter isn’t a data type constrained to never exceed the maximum. The compiler can’t know at compile time whether it’s out of bounds.
There may be a way to use C++ to constrain a parameter’s integral type to a range, but I can’t think of it. C++ is oceanic in its Syntax & semantics. Even though it was my primary language for over 30 years, there were still things I never learned.
in Rack/include/engine/Port.hpp I inserted the following pragma directives to get rid of the warnings
void setChannels(int channels) {
// If disconnected, keep the number of channels at 0.
if (this->channels == 0) {
return;
}
// Set higher channel voltages to 0
for (int c = channels; c < this->channels; c++) {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Warray-bounds"
voltages[c] = 0.f;
#pragma GCC diagnostic pop
}
// Don't allow caller to set port as disconnected
if (channels == 0) {
channels = 1;
}
this->channels = channels;
}
Did someone try using gcc built-ins for this?
Like so:
void setChannels(int channels) {
// If disconnected, keep the number of channels at 0.
if (this->channels == 0) {
return;
}
// Set higher channel voltages to 0
for (int c = channels; c < this->channels; c++) {
if (c >= PORT_MAX_CHANNELS)
__builtin_unreachable();
voltages[c] = 0.f;
}
// Don't allow caller to set port as disconnected
if (channels == 0) {
channels = 1;
}
this->channels = channels;
}
the __builtin_unreachable is a compile-time hint, it generates no extra code.
EDIT: just tried on Linux with GCC 11.3 and it works here, no more annoying warnings