Path: csiph.com!eternal-september.org!feeder.eternal-september.org!nntp.eternal-september.org!.POSTED!not-for-mail From: Tim Rentsch Newsgroups: comp.lang.c++ Subject: Re: Array size validity and SFINAE Date: Mon, 02 Mar 2026 00:38:52 -0800 Organization: A noiseless patient Spider Lines: 80 Message-ID: <86zf4qeicj.fsf@linuxsc.com> References: <10nn6pp$su58$1@dont-email.me> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Injection-Date: Mon, 02 Mar 2026 08:39:08 +0000 (UTC) Injection-Info: dont-email.me; posting-host="879346d16fc7c1cd3f18baf5c462c148"; logging-data="1046631"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+58bB17pr4tof5Rrv/TuyIX642TYESOeY=" User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.4 (gnu/linux) Cancel-Lock: sha1:XPyh4oUELGLXDWuE93OfXDgzdDM= sha1:4QnGrRIf4np+xBVZ2rIFqK8ivRY= Xref: csiph.com comp.lang.c++:123505 Andrey Tarasevich writes: > #include > > struct S { static constexpr int N = -1; }; > > template void foo(int [T::N]) > { > std::cout << "array" << std::endl; > } > > template void foo(...) > { > std::cout << "..." << std::endl; > } > > int main() > { > foo(0); > } > > GCC outputs "array", Clang and MSVC output "..." > > The struct definition can be changed to `struct S {};` with the same > behavior from GCC. I.e. in template contexts GCC does not check the > validity of the size specified in array parameter declaration: it > doesn't care whether it is positive, it doesn't even care whether the > nested name exists. One can guess that this is most likely a > consequence of the array parameter type adjustment, which makes the > size essentially "disappear". However, it still does not necessarily > mean that such array parameter declaration should be accepted as > valid. > > So, who's right here standard-wise? I certainly don't claim to be a C++ language lawyer; at best I might agree to be termed a language paralegal. That said, here are my thoughts. First, the struct S is irrelevant; it has no bearing on the question or the observed behavior. Second, clang is right, and gcc is wrong. The output under gcc of "array" would seem to imply that int::N exists, but it doesn't. Third, if we add a statement int fred = T::N; to the first template, gcc gives an error, whereas clang still outputs '...'. My understanding of SFINAE matches what clang does, and does not match what gcc does. Fourth, if after adding 'int fred = ...' to the first template, we change the call in main() to foo(0) then gcc again outputs 'array', whereas clang outputs '...'. Fifth, if after adding 'int fred = ...' to the first template, we define a new struct struct U { static constexpr unsigned int N = -1; }; and change the invocation in main() to foo(0) then both gcc and clang both output 'array'. Incidentally, trying to define an analogous pair of overloaded functions simply rejects the definition with a negative value for the extent of the array parameter. That holds for both gcc and clang. In every case clang does what I expect, and is consistent with what I understand about SFINAE. I can't say the same for gcc. So, either my understanding of SFINAE is messed up, or gcc is confused about something.