473,466 Members | 4,850 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

How to use a const pointer in switch case ?

hi,

I have define in a head file like this:
#define GLUT_BITMAP_9_BY_15 ((void*)2)
#define GLUT_BITMAP_8_BY_13 ((void*)3)
#define GLUT_BITMAP_TIMES_ROMAN_10 ((void*)4)
#define GLUT_BITMAP_TIMES_ROMAN_24 ((void*)5)

then I use the constan in switch, like:
switch(font) {
case GLUT_BITMAP_8_BY_13: bitmapHeight = 13;
break;
case GLUT_BITMAP_9_BY_15: bitmapHeight = 15;
break;
case GLUT_BITMAP_TIMES_ROMAN_10: bitmapHeight
= 10; break;
case GLUT_BITMAP_TIMES_ROMAN_24: bitmapHeight
= 24; break;
case GLUT_BITMAP_HELVETICA_10: bitmapHeight =
10; break;
case GLUT_BITMAP_HELVETICA_12: bitmapHeight =
12; break;
case GLUT_BITMAP_HELVETICA_18: bitmapHeight =
18; break;
}
Then I use gcc to compile them, the gcc always complain:

a8.c:261: error: pointers are not permitted as case values
a8.c:261: error: case label does not reduce to an integer constant
a8.c:262: error: pointers are not permitted as case values
a8.c:262: error: case label does not reduce to an integer constant

And I can not convert the GLUT_BITMAP_9_BY_15 to a integer
constant, and can not complain pass, how to solve it?

I know I can use if ... elseif ... statement, really I can not use
switch in this case? switch can just only use a integer constant? I
read the "the C programming language", it said so.

And for what reason the header file will define the const to a
(void *)?

any one can give me a answer?

thanks.

Mar 27 '07 #1
11 7902
qu*******@mail.whut.edu.cn said:
hi,

I have define in a head file like this:
#define GLUT_BITMAP_9_BY_15 ((void*)2)
#define GLUT_BITMAP_8_BY_13 ((void*)3)
#define GLUT_BITMAP_TIMES_ROMAN_10 ((void*)4)
#define GLUT_BITMAP_TIMES_ROMAN_24 ((void*)5)
Why? That's a daft thing to do.
then I use the constan in switch, like:
switch(font) {
case GLUT_BITMAP_8_BY_13: bitmapHeight = 13;
Can't do that. Case values are supposed to be constant integer
expressions.
Then I use gcc to compile them, the gcc always complain:

a8.c:261: error: pointers are not permitted as case values
Right.
a8.c:261: error: case label does not reduce to an integer constant
Right again.
And I can not convert the GLUT_BITMAP_9_BY_15 to a integer
constant, and can not complain pass, how to solve it?
Use integer constants instead of pointers.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at the above domain, - www.
Mar 27 '07 #2
On 3ÔÂ27ÈÕ, ÏÂÎç5ʱ47·Ö, Richard Heathfield <r...@see.sig.invalidwrote:
quakew...@mail.whut.edu.cn said:
hi,
I have define in a head file like this:
#define GLUT_BITMAP_9_BY_15 ((void*)2)
#define GLUT_BITMAP_8_BY_13 ((void*)3)
#define GLUT_BITMAP_TIMES_ROMAN_10 ((void*)4)
#define GLUT_BITMAP_TIMES_ROMAN_24 ((void*)5)

Why? That's a daft thing to do.
I do not want to use like that, but that is the glut's head.
(glut is a mini package for opengl.)
Mar 27 '07 #3
qu*******@mail.whut.edu.cn wrote:
hi,

I have define in a head file like this:
#define GLUT_BITMAP_9_BY_15 ((void*)2)
#define GLUT_BITMAP_8_BY_13 ((void*)3)
#define GLUT_BITMAP_TIMES_ROMAN_10 ((void*)4)
#define GLUT_BITMAP_TIMES_ROMAN_24 ((void*)5)

And for what reason the header file will define the const to a
(void *)?
The only one I can think of is to antagonise users! What a perverse
thing to do.

--
Ian Collins.
Mar 27 '07 #4
qu*******@mail.whut.edu.cn wrote:

#define GLUT_BITMAP_9_BY_15 ((void*)2)
#define GLUT_BITMAP_8_BY_13 ((void*)3)
#define GLUT_BITMAP_TIMES_ROMAN_10 ((void*)4)
#define GLUT_BITMAP_TIMES_ROMAN_24 ((void*)5)
In <GL/glut.h>. Good grief! Why did they have to do that!

then I use the constan in switch, like:
switch(font) {
case GLUT_BITMAP_8_BY_13: bitmapHeight = 13;
[ ... ]
}
Then I use gcc to compile them, the gcc always complain:
a8.c:261: error: pointers are not permitted as case values
a8.c:261: error: case label does not reduce to an integer constant
And rightly it should. Try casting them to int,

/* Editorial comment about braindamaged interface goes here.
* You should avoid editorial comments in your code, but
* this one is hard to resist.
*/
switch((int)font) {
case (int) GLUT_BITMAP_8_BY_13: bitmapHeight= 13;
/* ... */
}

because I think (int)((void *)3) is an integer constant. You
may need to cast the "font" variable as well, depending on its
declared type.
--
pa at panix dot com
Mar 27 '07 #5
Pierre Asselin wrote:
qu*******@mail.whut.edu.cn wrote:
#define GLUT_BITMAP_9_BY_15 ((void*)2)
#define GLUT_BITMAP_8_BY_13 ((void*)3)
#define GLUT_BITMAP_TIMES_ROMAN_10 ((void*)4)
#define GLUT_BITMAP_TIMES_ROMAN_24 ((void*)5)

In <GL/glut.h>. Good grief! Why did they have to do that!

then I use the constan in switch, like:
switch(font) {
case GLUT_BITMAP_8_BY_13: bitmapHeight = 13;
[ ... ]
}
Then I use gcc to compile them, the gcc always complain:
a8.c:261: error: pointers are not permitted as case values
a8.c:261: error: case label does not reduce to an integer constant

And rightly it should. Try casting them to int,

/* Editorial comment about braindamaged interface goes here.
* You should avoid editorial comments in your code, but
* this one is hard to resist.
*/
switch((int)font) {
case (int) GLUT_BITMAP_8_BY_13: bitmapHeight= 13;
/* ... */
}

because I think (int)((void *)3) is an integer constant. You
may need to cast the "font" variable as well, depending on its
declared type.
(int)((void *)3) is not an integer constant expression and cannot be
portably used in a case label. (However, multiple compilers behave as
if it is an integer constant expression and accept such constructs
without any diagnostic.)

Mar 27 '07 #6
(Pierre Asselin) wrote:
>#define GLUT_BITMAP_9_BY_15 ((void*)2)
#define GLUT_BITMAP_8_BY_13 ((void*)3)
...
In <GL/glut.h>. Good grief! Why did they have to do that!
I saw similar things many times.
It's a side effect of creating opaque data structures, (accessed
trough a void pointer,) and matching a function signature when
providing literal values as parameters to functions expecting those
opaque structures.
(Of course this relies on the assumption that small integers would not
have the same representation as the address of a "real" structure)
For example,
---- in library.h ----

extern void *h1;
extern void *h2;

extern void func1(void *v,...);
extern void func2(void *v,...);

/* valid arguments for func1, func2 ... */

#define H1 (&h1)
#define H2 (&h2)

#define P1 ((void*)1)
#define P2 ((void*)2)

---- In library.c ----

struct hidden
{
...
};

struct hidden h1 = { ... };
struct hidden h2 = { ... };

void func1(void *v, ...)
{
struct hidden *h = (struct hidden*) v;
v-...
...
}

void func2(void *v, ...)
{
struct hidden *h = (struct hidden*) v;
v-...
...
}


Roberto Waltman

[ Please reply to the group,
return address is invalid ]
Mar 27 '07 #7
On Tue, 27 Mar 2007 22:11:26 +0100, Roberto Waltman
<us****@rwaltman.netwrote:
>(Pierre Asselin) wrote:
>>#define GLUT_BITMAP_9_BY_15 ((void*)2)
#define GLUT_BITMAP_8_BY_13 ((void*)3)
...
In <GL/glut.h>. Good grief! Why did they have to do that!

I saw similar things many times.
It's a side effect of creating opaque data structures, (accessed
trough a void pointer,) and matching a function signature when
providing literal values as parameters to functions expecting those
opaque structures.
(Of course this relies on the assumption that small integers would not
have the same representation as the address of a "real" structure)
For example,
---- in library.h ----

extern void *h1;
extern void *h2;

extern void func1(void *v,...);
extern void func2(void *v,...);

/* valid arguments for func1, func2 ... */

#define H1 (&h1)
#define H2 (&h2)

#define P1 ((void*)1)
#define P2 ((void*)2)

---- In library.c ----
#include "library.h"
struct hidden
{
...
};

struct hidden h1 = { ... };
struct hidden h2 = { ... };

void func1(void *v, ...)
{
struct hidden *h = (struct hidden*) v;
v-...
That should have been h-...

A more useful example:

void func2(void *v, ...)
{
struct hidden *h;
if ((v == P1) || (v == P2))
{
/* do something not using v as */
/* a struct pointer */
...
}
else
{
/* do something using v as */
/* a struct pointer */

h = (struct hidden*) v;
h-...
...
}

Roberto Waltman

[ Please reply to the group,
return address is invalid ]
Mar 27 '07 #8
Roberto Waltman <us****@rwaltman.netwrites:
(Pierre Asselin) wrote:
>>#define GLUT_BITMAP_9_BY_15 ((void*)2)
#define GLUT_BITMAP_8_BY_13 ((void*)3)
...
In <GL/glut.h>. Good grief! Why did they have to do that!

I saw similar things many times.
It's a side effect of creating opaque data structures, (accessed
trough a void pointer,) and matching a function signature when
providing literal values as parameters to functions expecting those
opaque structures.
(Of course this relies on the assumption that small integers would not
have the same representation as the address of a "real" structure)
[snip]

In fact, the C standard does something similar. The second argument
to the signal() function, and its return value, is of a function
pointer type. The standard defines three macros, SIG_DFL, SIG_ERR,
and SIG_IGN, which are constant expressions of this type. They must
have distinct values unequal to the address of any declarable
function.

<OT>
In the implementations I've checked, they have the values 0, -1, and
1, respectively, converted to the appropriate type (These
implementations allow conversions between integer types and
pointer-to-function types.) Of course, these specific values are not
required.
</OT>

As you say, in both cases this depends on the assumption that small
integers converted to pointers don't match the address of any actual
structure or function. In the case of <signal.h>, the declarations
are part of the implementation, which is free to make whatever
system-specific assumptions it can get away with. The authors of GLUT
apparently chose to make the same kind of assumption, which is not
unreasonable; GLUT probably won't even compile on a DS9K.

If you *don't* want to make that kind of assumption, you could make
the macros expand to the addresses of static structures or functions
that are otherwise unused. For example:

static struct whatever Dummy_GLUT_BITMAP_9_BY_15;
#define GLUT_BITMAP_9_BY_15 ((void*)&Dummy_GLUT_BITMAP_9_BY_15)

...

static void __Dummy_SIG_DFL(int) { abort(); }
/* don't call this function */
#define SIG_DFL (&__Dummy_Sig_DFL)

(The "& is usually unnecessary for a function designator, but in this
case it allows SIG_DFL to be used as the operand of sizeof, and
disallows its use as the operand of another "&".)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Mar 27 '07 #9
Keith Thompson wrote:
Roberto Waltman <us****@rwaltman.netwrites:
(Pierre Asselin) wrote:
>#define GLUT_BITMAP_9_BY_15 ((void*)2)
#define GLUT_BITMAP_8_BY_13 ((void*)3)
...
In <GL/glut.h>. Good grief! Why did they have to do that!
I saw similar things many times.
It's a side effect of creating opaque data structures, (accessed
trough a void pointer,) and matching a function signature when
providing literal values as parameters to functions expecting those
opaque structures.
(Of course this relies on the assumption that small integers would not
have the same representation as the address of a "real" structure)
[snip]

In fact, the C standard does something similar. The second argument
to the signal() function, and its return value, is of a function
pointer type. The standard defines three macros, SIG_DFL, SIG_ERR,
and SIG_IGN, which are constant expressions of this type. They must
have distinct values unequal to the address of any declarable
function.

<OT>
In the implementations I've checked, they have the values 0, -1, and
1, respectively, converted to the appropriate type (These
implementations allow conversions between integer types and
pointer-to-function types.) Of course, these specific values are not
required.
</OT>
Are you saying implementations are not required to allow conversions
between integer types and pointer-to-function types? I'm aware that
it's allowed that no integer type is large enough to store a function
pointer, but I was under the impression that the conversion itself was
required to be supported -- that is,

int main(void) { return 0 && (int) &main; }

is strictly conforming as far as I know.

Mar 28 '07 #10
"Harald van Dijk" <tr*****@gmail.comwrites:
Keith Thompson wrote:
[...]
><OT>
In the implementations I've checked, they have the values 0, -1, and
1, respectively, converted to the appropriate type (These
implementations allow conversions between integer types and
pointer-to-function types.) Of course, these specific values are not
required.
</OT>

Are you saying implementations are not required to allow conversions
between integer types and pointer-to-function types? I'm aware that
it's allowed that no integer type is large enough to store a function
pointer, but I was under the impression that the conversion itself was
required to be supported -- that is,

int main(void) { return 0 && (int) &main; }

is strictly conforming as far as I know.
Yes, that was what I was saying. Alas, I was wrong, wrong, wrong.

C99 6.3.2.3:

An integer may be converted to any pointer type.
[...]
Any pointer type may be converted to an integer type.

What I was thinking of was the fact that function pointers can't be
directly converted to object pointers or vice versa.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Mar 28 '07 #11
Keith Thompson wrote:
"Harald van Dijk" <tr*****@gmail.comwrites:
>Keith Thompson wrote:
[...]
>>>
In the implementations I've checked, they have the values 0, -1,
and 1, respectively, converted to the appropriate type (These
implementations allow conversions between integer types and
pointer-to-function types.) Of course, these specific values
are not required.

Are you saying implementations are not required to allow
conversions between integer types and pointer-to-function types?
I'm aware that it's allowed that no integer type is large enough
to store a function pointer, but I was under the impression that
the conversion itself was required to be supported -- that is,

int main(void) { return 0 && (int) &main; }

is strictly conforming as far as I know.

Yes, that was what I was saying. Alas, I was wrong, wrong, wrong.

C99 6.3.2.3:

An integer may be converted to any pointer type.
[...]
Any pointer type may be converted to an integer type.

What I was thinking of was the fact that function pointers can't
be directly converted to object pointers or vice versa.
That emasculated quotation is very dangerous. It might persuade
someone that they can actually do it. The full quote follows.

[#5] An integer may be converted to any pointer type.
Except as previously specified, the result is
implementation-defined, might not be properly aligned, and
might not point to an entity of the referenced type.49)

[#6] Any pointer type may be converted to an integer type.
Except as previously specified, the result is
implementation-defined. If the result cannot be represented
in the integer type, the behavior is undefined. The result
need not be in the range of values of any integer type.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>

--
Posted via a free Usenet account from http://www.teranews.com

Mar 28 '07 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: CoolPint | last post by:
Can anyone clearly explain the difference between constant reference to pointers and reference to constant pointers? What is const int * & ? Is it a constant reference to a pointer to an...
20
by: Corno | last post by:
Hi all, There's probably a good reason why a const object can call non const functions of the objects where it's member pointers point to. I just don't see it. For me, that makes the the const...
19
by: Thomas Matthews | last post by:
Hi, Given a structure of pointers: struct Example_Struct { unsigned char * ptr_buffer; unsigned int * ptr_numbers; }; And a function that will accept the structure:
12
by: Steven T. Hatton | last post by:
Any opinions or comments on the following? I don't say it below, but I came out on the side of using enumerations over static constants. /* I'm trying to figure out the pros and cons of using...
7
by: al | last post by:
char s = "This string literal"; or char *s= "This string literal"; Both define a string literal. Both suppose to be read-only and not to be modified according to Standard. And both have...
18
by: DaveLessnau | last post by:
I'm trying to learn C on my own and, apparently, my brain went on vacation somewhere. I just can't figure out how to parse the following function call: "void fillDeck( Card * const wDeck, const...
10
by: kkirtac | last post by:
Hi, i have a void pointer and i cast it to an appropriate known type before using. The types which i cast this void* to are, from the Intel's open source computer vision library. Here is my piece...
10
by: flopbucket | last post by:
Hi, Is this legal? std::string foo() { std::string xyz = "FOO"; return xyz; }
8
by: Jaco Naude | last post by:
Hi I've been struggling with something that should be very simple to solve... Basically, I get a const Obj* from a function and I need to send a pointer to this object to a function accepting...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.