gcc: error: case label does not reduce to an integer constant

S

SysSpider

Hi again,

This is my problem: when i try to compile the code that contains the
function below, i get this:

--
gcc:21: error: case label does not reduce to an integer constant
gcc:24: error: case label does not reduce to an integer constant
--

Now, I (think that I) understand the error, but cryptMsg surely
doesn't look like a constant to me...

Thanks for help,
SysSpider

P.S.: btw, for those interested, I'm implementing the "one time pad"
cryptography system, although that isn't important to the problem...


--Source code--
void decryptMsg(int sizeMsg) {
int i;
char cryptMsg[sizeMsg], key[sizeMsg];

printf("\nEnter the encrypted message (no spaces): ");
scanf("%s", cryptMsg);
printf("Enter the used key (no spaces): ");
scanf("%s", key);

printf("\nThe message is:\n");

for(i = 0; i < sizeMsg; i++)
{
if(i%2 == 0 && i != 0) printf(" ");

switch(cryptMsg) //Here starts the problem
{
case charToInt(cryptMsg) < charToInt(key): //Error
printf("%d", charToInt(cryptMsg) + 10 -
charToInt(key));
break;
case charToInt(cryptMsg) >= charToInt(key): //Error
printf("%d", charToInt(cryptMsg) -
charToInt(key));
break;
default:
printf("\nError!\n");
break;
}
}
}
--End of source--
 
B

Ben Pfaff

Presumably for this line and the similar one below it:
case charToInt(cryptMsg) < charToInt(key): //Error
Now, I (think that I) understand the error, but cryptMsg surely
doesn't look like a constant to me...


Exactly. A case label must be an integer constant. You cannot
do this sort of test with a switch statement. I suggest using an
if statement instead.
 
J

Joe Wright

SysSpider said:
Hi again,

This is my problem: when i try to compile the code that contains the
function below, i get this:

--
gcc:21: error: case label does not reduce to an integer constant
gcc:24: error: case label does not reduce to an integer constant
--

Now, I (think that I) understand the error, but cryptMsg surely
doesn't look like a constant to me...

Thanks for help,
SysSpider

P.S.: btw, for those interested, I'm implementing the "one time pad"
cryptography system, although that isn't important to the problem...


--Source code--
void decryptMsg(int sizeMsg) {
int i;
char cryptMsg[sizeMsg], key[sizeMsg];

printf("\nEnter the encrypted message (no spaces): ");
scanf("%s", cryptMsg);
printf("Enter the used key (no spaces): ");
scanf("%s", key);

printf("\nThe message is:\n");

for(i = 0; i < sizeMsg; i++)
{
if(i%2 == 0 && i != 0) printf(" ");

switch(cryptMsg) //Here starts the problem
{
case charToInt(cryptMsg) < charToInt(key): //Error
printf("%d", charToInt(cryptMsg) + 10 -
charToInt(key));
break;
case charToInt(cryptMsg) >= charToInt(key): //Error
printf("%d", charToInt(cryptMsg) -
charToInt(key));
break;
default:
printf("\nError!\n");
break;
}
}
}
--End of source--


It won't work your way Spider, give it up with switch(). C's case
does not take an expression. It takes a constant. You have to know
in advance what the cases are looking for.

switch(getnum()) {
case 1: fun(1); break;
case 2: fun(2); break;
default: fun(3);
}

The canonical 'exclusive case' construct can be done like this..

if (case1)
fun(1);
else if (case2)
fun(2);
else
fun(3);

...where case1 and case2 are expressions of 0 or not-0.
 
C

Christopher Benson-Manica

Ben Pfaff said:
A case label must be an integer constant.

That's the same as saying that case labels must have integer values
computable at compile time, isn't it? (fmi)
 
J

john_bode

SysSpider said:
Hi again,

This is my problem: when i try to compile the code that contains the
function below, i get this:

--
gcc:21: error: case label does not reduce to an integer constant
gcc:24: error: case label does not reduce to an integer constant
--

Now, I (think that I) understand the error, but cryptMsg surely
doesn't look like a constant to me...

Thanks for help,
SysSpider

P.S.: btw, for those interested, I'm implementing the "one time pad"
cryptography system, although that isn't important to the problem...


--Source code--
void decryptMsg(int sizeMsg) {
int i;
char cryptMsg[sizeMsg], key[sizeMsg];

printf("\nEnter the encrypted message (no spaces): ");
scanf("%s", cryptMsg);
printf("Enter the used key (no spaces): ");
scanf("%s", key);

printf("\nThe message is:\n");

for(i = 0; i < sizeMsg; i++)
{
if(i%2 == 0 && i != 0) printf(" ");

switch(cryptMsg) //Here starts the problem
{
case charToInt(cryptMsg) < charToInt(key): //Error
printf("%d", charToInt(cryptMsg) + 10 -
charToInt(key));
break;
case charToInt(cryptMsg) >= charToInt(key): //Error
printf("%d", charToInt(cryptMsg) -
charToInt(key));
break;
default:
printf("\nError!\n");
break;
}
}
}
--End of source--
 
F

Flash Gordon

That's the same as saying that case labels must have integer values
computable at compile time, isn't it? (fmi)

No.

# cat t.c
int foo( int x )
{
switch (x) {
case (1,2): return 1;
case 3: return 2;
default: return 4;
}
}
# gcc -ansi -pedantic t.c
t.c: In function `foo':
t.c:4: error: case label does not reduce to an integer constant
 
J

john_bode

Dammit, I *hate* the new Google interface.

Basically, what you're wanting to use here is an if-else statement,
*not* a switch:

if (charToInt(cryptMsg) < charToInt(keyMsg))
{
// do something
}
else // charToInt(cryptMsg) must be >= charToInt(keyMsg)
{
// do something else
}

You use a switch when you want to execute code based on the value of
the thing you're switching on; for example,

switch (cryptMsg)
{
case 'A':
// do something
break;

case 'B':
// do something else
break;

....
default:
// default case
break;
}

Case labels must evaluate to an integral constant expression, which a>b
is *not*.
 
B

Ben Pfaff

Christopher Benson-Manica said:
That's the same as saying that case labels must have integer values
computable at compile time, isn't it? (fmi)

As far as I can tell, yes. (Are you trying to trap me in some
kind of Standard lawyerese here, or are you just confused?)

Here is what the Standard says:
The expression of each case label shall be an integer
constant expression...
 
B

Ben Pfaff

Flash Gordon said:
No.

# cat t.c
int foo( int x )
{
switch (x) {
case (1,2): return 1;

Well, the statements are casually and informally equivalent. A
case constant like `1+2' is perfectly fine. You found a corner
case where an "integer value computable at compile time" is not
an "integer constant expression" as defined by the standard,
because the comma operator is not allowed in an integer constant
expression. But most *useful* constant expressions are valid as
case constants.
 
M

Mark McIntyre

On 28 Dec 2004 11:22:22 -0800, in comp.lang.c ,
Hi again,

This is my problem: when i try to compile the code that contains the
function below, i get this:

Not very surprising. Case labels must be constants. And
charToInt(cryptMsg) < charToInt(key)
isn't a constant.

Note that its the LABEL that must be constant, not the case being tested.
 
M

Mark McIntyre

That's the same as saying that case labels must have integer values
computable at compile time, isn't it? (fmi)

No, its not. They must be actual integer constants. Macros are ok, literals
are ok, results of expressions are not.
 
B

Ben Pfaff

Mark McIntyre said:
No, its not. They must be actual integer constants. Macros are ok, literals
are ok, results of expressions are not.

No, you're wrong. Let me repeat the quote from the Standard that
I posted earlier:
The expression of each case label shall be an integer
constant expression...
An integer constant expression is not necessarily just a literal.
 
C

Christopher Benson-Manica

Ben Pfaff said:
As far as I can tell, yes. (Are you trying to trap me in some
kind of Standard lawyerese here, or are you just confused?)

That's just how I would have answered the question, and I wanted to
know whether I would have been strictly correct (Flash's post suggests
that the answer is "no").

Me trying to language-lawyer you would be about as dumb as me trying
to do it to Dan Pop, or Dennis Ritchie himself for that matter :)
 
L

lonny.nettnay

Ben said:
int main(void){char p[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.\
\n",*q="kl BIcNBFr.NKEzjwCIxNJC";int i=sizeof p/2;char *strchr();int putchar(\
);while(*q){i+=strchr(p,*q++)-p;if(i>=(int)sizeof p)i-=sizeof p-1;putchar(p\
);}return 0;}


Hi Ben,

I had a little difficulty getting your program to work. You have a
'space' character in the variable - char *q - but no space in the
variable - char p[]. It took me a little bit of work to figure out that
it should go after the 'z.'.

Cute program. Thanks for the laugh.

Lonny
 
M

Michael Mair

Mark said:
Possibly. But I disagree.

And you are wrong.

I saw it earlier. :)

Then parse it again and try to get the semantics right this time ;-)

I didn't say it had to be. I'd be interested in examples of suitable
expressions you could use.

Everything that counts as a constant expression from
1
over
3<<2
to
(7+5)/6*4
Instead of the numbers, you of course can also use
symbolic and enumeration constants.


Cheers
Michael
 
L

Lawrence Kirby

On Wed, 29 Dec 2004 16:23:08 +0100, Michael Mair wrote:

....
Everything that counts as a constant expression from
1
over
3<<2

Things like

1U << 3

can be useful for bitmask constants.
to
(7+5)/6*4
Instead of the numbers, you of course can also use
symbolic and enumeration constants.

A couple more examples

sizeof array / sizeof *array /* Where array isn't a VLA */

(int)1.2345

Lawrence
 
B

Ben Pfaff

I had a little difficulty getting your program to work. You have a
'space' character in the variable - char *q - but no space in the
variable - char p[]. It took me a little bit of work to figure out that
it should go after the 'z.'.

I'm not sure what you're talking about. The program, as posted,
is this:

int main(void){char p[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.\
\n",*q="kl BIcNBFr.NKEzjwCIxNJC";int i=sizeof p/2;char *strchr();int putchar(\
);while(*q){i+=strchr(p,*q++)-p;if(i>=(int)sizeof p)i-=sizeof p-1;putchar(p\
);}return 0;}

There is a space at the beginning of the second line, which puts
it between the '.' and the '\n' in p[]. Perhaps you or your
newsreader dropped that somehow before compiling it.
 
M

Mark McIntyre

Then parse it again and try to get the semantics right this time ;-)

And parse my answer again, and try to understand it right this time :)
Everything that counts as a constant expression from
1
over
3<<2
to
(7+5)/6*4

Er, these are all literals (as far as I'm concerned). I suspect we have a
nomenclature disagreement.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top