0

I have the following C code:

unsigned long val = <my_size>;

switch(val)
{
 case (1L<<10): // 1KB
  // Do something
  break;
 case 1L<<20:  // 1MB
  // Do somnething
  break;
 case (1L<<30): // 1GB
  // Do something 
  break;
 case (1L<<40): // 1TB
  // Do something
  break;
 // Other cases
 default:
  // Do something
  break;
}

Now lint is giving me a warning saying
"Warning:44 Illegal Argument to Switch: Size Exceeds UB4"

So is it valid to use switch on a unsigned long?

I don't get any compilation errors but want to make sure my code works properly and there are no funny rollover type stuff going on.

There won't be too many case labels in the switch.

I was reading on this and came across - Why can't your switch statement data type be long, Java?

It looks like switch statement type shouldn't be long in case of Java. Is it true for C as well?

If needed: 1. I am using linux lint 2. gcc for compiler 3. platform is linux 64 bit

Community
  • 1
  • 1
L Lawliet
  • 2,565
  • 4
  • 26
  • 35
  • I am really confused by this code. Why are you adding those K, M, T, G suffixes to the integer literals? I am not entirely familiar with them. What do they do – Vality Aug 09 '16 at 21:53
  • @Vality just a quick way to say 1 KiloByte, 1 GigaByte, 1 TeraByte and so on to give an easy to read example where large case value could be justified. – L Lawliet Aug 10 '16 at 00:50
  • I have made a go at answering the question as is, however I suggest you take a quick look at http://stackoverflow.com/help/mcve . We prefer a minimal example that can actually be built and run, and produces the symptom described. So if possible provide some build-able code and enough info on your tools that we can reproduce your problem. Hopefully if so I might be able to give a more helpful answer. – Vality Aug 10 '16 at 04:36
  • @ValityI appreciate you trying to make it more compilable, but I think a simple switch statement in C was perfectly making the point. This was more of a C standards related question so I don't see why compiler and all such information is relevant. I assumed considering how common mega, kilo, giga etc are these days, saying 1M, 1G makes sufficient sense if it's not a code debugging issue. Also these suffixes generally imply power of 2 by the way. – L Lawliet Aug 10 '16 at 21:00
  • 2
    What is the range of `unsigned long` on your system? If it's 32 bits, then `1L << 40` has undefined behavior. There are a lot of different lint programs; exactly which one are you using (and what is "UB4")? The only Google hits I get for "Illegal Argument to Switch: Size Exceeds" are your question and a copy of it on a site that apparently steals content from Stack Overflow. – Keith Thompson Aug 10 '16 at 21:23
  • (I've reported the site; see http://meta.stackoverflow.com/q/253906/827263) – Keith Thompson Aug 10 '16 at 21:30
  • @KeithThompson Thanks for reporting the site. :) I am on a 64 bit system. UB4 is just alias for 4 byte unsigned int. Lint I am using is custom 'splint' build with support for specific aliases. I can't go in detail of why it's a custom version and not the splint version that you get from repo but essentially the linting part is identical to splint. – L Lawliet Aug 10 '16 at 21:43
  • Please post a [MCVE](http://stackoverflow.com/help/mcve). Also include in the program some output to verify the size of `unsigned long`, don't just assume "oh i'm on a 64bit system, it will be 64bit" – M.M Aug 10 '16 at 23:04
  • In 64-bit Windows long is 32 bits. The size of a type and register size have no relation whatsoever – phuclv Aug 11 '16 at 00:39

1 Answers1

0

No, unlike Java, C permits that the control statement of a switch statement be any integer type. This includes int, long, unsigned long, uint32_t and pretty much any other integral type defined in the standard.

Unfortunately your code does not seem to be real working code, and is certainly not a MCVE so I can only speculate on the actual issue at hand. In addition I do not know which linting software or compiler you use so cannot easily look up the error message.

However I suspect that the most likely problem is that the largest of your case labels exceeds the maximum value of the control statement's type. For example if unsigned long is 32 bits on your system your program may have a case label larger than that therefore a warning would be appropriate if this label cannot occur.

Another possibility is that your switch has more labels than the implementation limit for cases in a single switch on your system. An implementation is allowed to set this limit.

I would likely be able to give more helpful info if an actual MCVE was given but as it is my answer is as given.

TLDR: Yes, a switch can use unsigned long or any other integer type

Vality
  • 6,577
  • 3
  • 27
  • 48
  • Any link to some C standard docs to back up your claim ? Since it's compiling fine I know that the C most likely shouldn't have any issue with it but this can also just gcc going the extra mile. If it's not officially supported, this can cause issues with other compilers or later on which I want avoid. Apart from that it would also be good to know for future. Since linux lint enforces the C standards more rigidly, if its complaining, its best to check. Eg. gcc won't cry about line comment in C code but lint would which are not by C standards. I wanted to know if it was the same case here. – L Lawliet Aug 10 '16 at 21:14
  • No exceeding the case clause limit is not the problem here. And like I said i am not getting an 'Error' from lint or gcc but it's just a 'Warning' – L Lawliet Aug 10 '16 at 21:17
  • @Siddharth: [N1570](http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf): "The controlling expression of a **`switch`** statement shall have integer type.". There is no restriction that would forbid using `unsigned long`. – Keith Thompson Aug 10 '16 at 21:21
  • Also about the MCVE, I mean no disrespect, but I am not sure how much more simple do I need to make a straight forward switch statement switching on an unsigned long variable. Just put in any value even 0 and try to lint the c file. You will hit the warning. It makes sense for debugging or even a little more complex code example but that's totally not the case here. – L Lawliet Aug 10 '16 at 21:23
  • @Siddharth for an MCVE the problem is not the minimal, but the complete. Your given code does not compile. It is not in a function, there is no main and there is even some illegal syntax. Nobody can run your code as it is. It should be an actual usable C program ideally or at least a function someone can compile. – Vality Aug 10 '16 at 22:10