Quantcast
Channel: Active questions tagged gcc - Stack Overflow
Viewing all articles
Browse latest Browse all 22002

Should a switch statement always contain a default if it initializes local variables?

$
0
0

Here's a piece of code from the FastNoise library of Jordan Peck. It gives a whole lot of compiler warnings, among which is this particular switch statement. Here you can see that variables xs, ys and zs are defined in a switch statement that lacks a default case. The justification is that since m_interp is an enum, "all" cases are covered explicitly in the switch.

However, when compiling this code with the latest gcc version 9.3.0 (Arch Linux 9.3.0-1), it warns about the mentioned variables (-Wmaybe-uninitialized). Indeed this is very bad, if it ever happens that an unexpected value reaches this switch statement, because it is tedious to debug code that uses undefined variables. I would say, here, defensive programming is perfectly justified even if in theory all enum values are covered. However, it has also been suggested that the latest gcc compiler is at fault here as it should not issue such a warning in the first place.

I know similar question has already been asked but it fails to mention the special case where variables are given their value for the first time within the switch statement. While normally it may be OK to omit the default case, doing it here can result in very disturbing bugs (undefined behavior). Is the GCC latest version at fault here, giving a false-positive warning? Or is this actually bad programming practice and the library's creator is at fault? Looking at the rest of the code I'd say it's the latter because the code also uses tabs instead of spaces, DOS-style line endings instead of Unix style and in addition to -Wmaybe-uninitialized it also has issues with -Wstrict-aliasing and -Wimplicit-fallthrough.

If GCC is giving a false-positive here, then I'm sure it should be reported accordingly. The question is, is it really a false-positive?

For the record, I would have amended the original discussion but apparently my Stackoverflow reputation is too low so I can't even make comments. Hence, I had no other way than to create a new topic to discuss this matter.

FN_DECIMAL FastNoise::SingleValue(unsigned char offset, FN_DECIMAL x, FN_DECIMAL y, FN_DECIMAL z) const{    int x0 = FastFloor(x);    int y0 = FastFloor(y);    int z0 = FastFloor(z);    int x1 = x0 + 1;    int y1 = y0 + 1;    int z1 = z0 + 1;    FN_DECIMAL xs, ys, zs;    switch (m_interp)    {    case Linear:        xs = x - (FN_DECIMAL)x0;        ys = y - (FN_DECIMAL)y0;        zs = z - (FN_DECIMAL)z0;        break;    case Hermite:        xs = InterpHermiteFunc(x - (FN_DECIMAL)x0);        ys = InterpHermiteFunc(y - (FN_DECIMAL)y0);        zs = InterpHermiteFunc(z - (FN_DECIMAL)z0);        break;    case Quintic:        xs = InterpQuinticFunc(x - (FN_DECIMAL)x0);        ys = InterpQuinticFunc(y - (FN_DECIMAL)y0);        zs = InterpQuinticFunc(z - (FN_DECIMAL)z0);        break;    }    FN_DECIMAL xf00 = Lerp(ValCoord3DFast(offset, x0, y0, z0), ValCoord3DFast(offset, x1, y0, z0), xs);    FN_DECIMAL xf10 = Lerp(ValCoord3DFast(offset, x0, y1, z0), ValCoord3DFast(offset, x1, y1, z0), xs);    FN_DECIMAL xf01 = Lerp(ValCoord3DFast(offset, x0, y0, z1), ValCoord3DFast(offset, x1, y0, z1), xs);    FN_DECIMAL xf11 = Lerp(ValCoord3DFast(offset, x0, y1, z1), ValCoord3DFast(offset, x1, y1, z1), xs);    FN_DECIMAL yf0 = Lerp(xf00, xf10, ys);    FN_DECIMAL yf1 = Lerp(xf01, xf11, ys);    return Lerp(yf0, yf1, zs);}

Viewing all articles
Browse latest Browse all 22002

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>