Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C Programming (http://www.velocityreviews.com/forums/f42-c-programming.html)
-   -   understanding enum type (http://www.velocityreviews.com/forums/t739043-understanding-enum-type.html)

arnuld 11-29-2010 06:48 AM

understanding enum type
 
From section 6.2.5, point number 16 in (n1256.pdf):

An enumeration comprises a set of named integer values. Each distinct
enumeration constitutes a different enumerated type.

Now I don' get this. Does it say 2 different enum types are different ?
Practically, they are not:


#include <stdio.h>


enum RET_VALUES_1 { VAL_FAIL = 0 };
enum RET_VALUES_2 { VAL_FALSE = 0 };


int main(void)
{
enum RET_VALUES_1 j1 = VAL_FAIL;
enum RET_VALUES_2 j2 = VAL_FALSE;

if(j1 == j2)
{
printf("oops! 2 enum types are equal :-/ \n");
}


return 0;
}
================== OUTPUT ======================
[arnuld@dune programs]$ gcc -ansi -pedantic -Wall -Wextra enum.c
[arnuld@dune programs]$ ./a.out
oops! 2 enum types are equal :-/
[arnuld@dune programs]$


--
www.lispmachine.wordpress.com

Joachim Schmitz 11-29-2010 07:16 AM

Re: understanding enum type
 
arnuld wrote:
> From section 6.2.5, point number 16 in (n1256.pdf):
>
> An enumeration comprises a set of named integer values. Each distinct
> enumeration constitutes a different enumerated type.
>
> Now I don' get this. Does it say 2 different enum types are different
> ? Practically, they are not:
>
>
> #include <stdio.h>
>
>
> enum RET_VALUES_1 { VAL_FAIL = 0 };
> enum RET_VALUES_2 { VAL_FALSE = 0 };
>
>
> int main(void)
> {
> enum RET_VALUES_1 j1 = VAL_FAIL;
> enum RET_VALUES_2 j2 = VAL_FALSE;
>
> if(j1 == j2)
> {
> printf("oops! 2 enum types are equal :-/ \n");
> }
>
>
> return 0;
> }
> ================== OUTPUT ======================
> [arnuld@dune programs]$ gcc -ansi -pedantic -Wall -Wextra enum.c
> [arnuld@dune programs]$ ./a.out
> oops! 2 enum types are equal :-/
> [arnuld@dune programs]$


The types are different, their values are not.

char c = 0;
int i = 0;

if ( i == c )
printf("oops!, two integer types, char and int, are equal???\n");

Bye, Jojo

Keith Thompson 11-29-2010 09:44 AM

Re: understanding enum type
 
arnuld <sunrise@invalid.address> writes:
> From section 6.2.5, point number 16 in (n1256.pdf):
>
> An enumeration comprises a set of named integer values. Each distinct
> enumeration constitutes a different enumerated type.
>
> Now I don' get this. Does it say 2 different enum types are different ?
> Practically, they are not:
>

[...]
>
> enum RET_VALUES_1 { VAL_FAIL = 0 };
> enum RET_VALUES_2 { VAL_FALSE = 0 };

[snip]

The fact that two types can be implicitly converted to one another
doesn't imply that the they're the same type. There are implicit
conversions between any two arithmetic types.

One way that the fact that two arithmetic types are distinct shows up is
that pointers to them are distinct, and there are no implicit
conversions between distinct pointer types (other than void*).

enum RET_VALUES_1 *p1;
enum RET_VALUES_2 *p2;
p1 = p2; /* constraint violation */

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Eric Sosman 11-29-2010 12:44 PM

Re: understanding enum type
 
On 11/29/2010 1:48 AM, arnuld wrote:
> From section 6.2.5, point number 16 in (n1256.pdf):
>
> An enumeration comprises a set of named integer values. Each distinct
> enumeration constitutes a different enumerated type.
>
> Now I don' get this. Does it say 2 different enum types are different ?


Yes.

> Practically, they are not:
>
>
> #include<stdio.h>
>
>
> enum RET_VALUES_1 { VAL_FAIL = 0 };
> enum RET_VALUES_2 { VAL_FALSE = 0 };
> [...]


All your program has shown is that both the enum types can
represent the value zero, and that instances of the two types can
be compared. Big deal: `unsigned char' and `long double' can both
represent zero and can be compared; do you think they are alike?

Try continuing this way:

void func(enum RET_VALUES_1);
void (*fptr)(enum RET_VALUES_2) = func;

--
Eric Sosman
esosman@ieee-dot-org.invalid

arnuld 12-01-2010 04:16 AM

Re: understanding enum type
 
> On Mon, 29 Nov 2010 07:44:44 -0500, Eric Sosman wrote:


> All your program has shown is that both the enum types can
> represent the value zero, and that instances of the two types can be
> compared. Big deal: `unsigned char' and `long double' can both
> represent zero and can be compared; do you think they are alike?


Okay, one more C-truth that supports the fact that it really takes 10
years to master C


> Try continuing this way:
>
> void func(enum RET_VALUES_1);
> void (*fptr)(enum RET_VALUES_2) = func;



[arnuld@dune programs]$ gcc -ansi -pedantic -Wall -Wextra enum.c
enum.c:9: warning: initialization from incompatible pointer type
/tmp/cclJPM48.o:(.data+0x0): undefined reference to `func'
collect2: ld returned 1 exit status
[arnuld@dune programs]$


If I use another declaration like:

void (*fptr2)(enum RET_VALUES_1) = func;

then I don't get incompatible pointer type warning. I understood that
they are different types and can hold same values.

Still, I never used function pointers(partly because I am scared of them
and partly because I never knew (still don't know) what they are useful
for). This reminds of a real life scenario (though OT) I have right now
in my place of work:


I have a function-1 and inside of it there is a call to function-A:

function-1() { .... fucntion-A() ....}

I have written 3 functions like this:

function-2() { ..... fucntion-B() .....}
function-3() { ..... function-C() .....}


Now the difference between all these function-1,2,3 is that only function
calls are different, rest 99^ of coding is same. Are function pointers
useful here ?




--
www.lispmachine.wordpress.com

Ike Naar 12-01-2010 10:13 AM

Re: understanding enum type
 
On 2010-12-01, arnuld <sunrise@invalid.address> wrote:
> I have a function-1 and inside of it there is a call to function-A:
>
> function-1() { .... fucntion-A() ....}
>
> I have written 3 functions like this:
>
> function-2() { ..... fucntion-B() .....}
> function-3() { ..... function-C() .....}
>
> Now the difference between all these function-1,2,3 is that only function
> calls are different, rest 99^ of coding is same. Are function pointers
> useful here ?


Possibly. You could replace function-1, function-2 and function-3 by
a single function, say, function-N, that takes the inner function to be
called (function-A etcetera) as a parameter.

function-N(void (*callee)()) { ... (*callee)() ... }

Then, instead of

function-1()
function-2()
function-3()

use

function-N(&function-A)
function-N(&function-B)
function-N(&function-C)

--
ike@sdf.lonestar.org
SDF Public Access UNIX System - http://sdf.lonestar.org

BartC 12-01-2010 11:59 AM

Re: understanding enum type
 
"Ike Naar" <ike@otaku.freeshell.org> wrote in message
news:slrnifc7to.3a.ike@otaku.freeshell.org...
> On 2010-12-01, arnuld <sunrise@invalid.address> wrote:
>> I have a function-1 and inside of it there is a call to function-A:
>>
>> function-1() { .... fucntion-A() ....}
>>
>> I have written 3 functions like this:
>>
>> function-2() { ..... fucntion-B() .....}
>> function-3() { ..... function-C() .....}
>>
>> Now the difference between all these function-1,2,3 is that only function
>> calls are different, rest 99^ of coding is same. Are function pointers
>> useful here ?

>
> Possibly. You could replace function-1, function-2 and function-3 by
> a single function, say, function-N, that takes the inner function to be
> called (function-A etcetera) as a parameter.
>
> function-N(void (*callee)()) { ... (*callee)() ... }
>
> Then, instead of
>
> function-1()
> function-2()
> function-3()
>
> use
>
> function-N(&function-A)
> function-N(&function-B)
> function-N(&function-C)


The caller of function-1, function-2 and so on may not know that each will
call function-A, function-B, etc in turn, if the function bodies are not
visible.

This is a 'problem' for the implementer of function-'n' to sort out.
Presumably, since there are only 3 functions, the object is avoid
replicating a possible large body of code in each.

Possibly, use your function-N() scheme, the caller still calls
function-1/2/3(), but each of those now consists of code such as:

function-2(){ function-N(&function-B);}

Then the same interface is preserved.

--
Bartc



BartC 12-01-2010 12:09 PM

Re: understanding enum type
 


"arnuld" <sunrise@invalid.address> wrote in message
news:4cf5cc37$0$23752$14726298@news.sunsite.dk...
>> On Mon, 29 Nov 2010 07:44:44 -0500, Eric Sosman wrote:

>
>
>> All your program has shown is that both the enum types can
>> represent the value zero, and that instances of the two types can be
>> compared. Big deal: `unsigned char' and `long double' can both
>> represent zero and can be compared; do you think they are alike?

>
> Okay, one more C-truth that supports the fact that it really takes 10
> years to master C


That's my feeling too; on the face of it, C seems quite simple..

Anyway, these different types all have a slightly different version of zero,
for example 0 is an int, and 0.0 is a double (or is it a float); but C
allows you to compare different numeric types by automatically converting
one to the more dominant type.

In the case of enums, I think their values have to be ints, so in:

enum Z{zero=0};

Then zero may be an int value, or an int literal (I'm not going to wade
through 700 pages of the standard to find out exactly what). It is anyway
not what you might expect (a Z-literal or whatever).

--
Bartc


Eric Sosman 12-01-2010 12:37 PM

Re: understanding enum type
 
On 11/30/2010 11:16 PM, arnuld wrote:
>> On Mon, 29 Nov 2010 07:44:44 -0500, Eric Sosman wrote:

>
>> All your program has shown is that both the enum types can
>> represent the value zero, and that instances of the two types can be
>> compared. Big deal: `unsigned char' and `long double' can both
>> represent zero and can be compared; do you think they are alike?

>
> Okay, one more C-truth that supports the fact that it really takes 10
> years to master C


If it takes ten years to learn that the value zero can be
represented in several different ways, perhaps you're in the wrong
line of work. :-)

>> Try continuing this way:
>>
>> void func(enum RET_VALUES_1);
>> void (*fptr)(enum RET_VALUES_2) = func;

>
>
> [arnuld@dune programs]$ gcc -ansi -pedantic -Wall -Wextra enum.c
> enum.c:9: warning: initialization from incompatible pointer type


And why are they incompatible? Because RET_VALUES_1 and
RET_VALUES_2 are not the same type, that's why. Point made.
(Keith Thompson's example is a clearer one, though.)

> I have a function-1 and inside of it there is a call to function-A:
>
> function-1() { .... fucntion-A() ....}
>
> I have written 3 functions like this:
>
> function-2() { ..... fucntion-B() .....}
> function-3() { ..... function-C() .....}
>
> Now the difference between all these function-1,2,3 is that only function
> calls are different, rest 99^ of coding is same. Are function pointers
> useful here ?


Quite possibly, if function-{A,B,C} have the same parameter
lists and return types. (If they disagree it may be *possible*,
but will certainly be clumsier.) Illustration, concretized just
a little bit for clarity:

/* The three functions you might want to call: */
void function_A(double);
void function_B(double);
void function_C(double);

/* A type that can point to any of them: */
typedef void (*FuncPtr)(double);

/* The omnibus caller function: */
void function_123(double x, FuncPtr func) {
...
func(x); /* some prefer `(*func)(x)'; no difference */
...
}

/* A few calls to the omnibus caller: */
int main(void) {
function_123(3.14, function_A);
function_123(2.78, function_B);
function_123(42.0, function_C);
return 0;
}

You could write it without the typedef, if desired, but I think
typedeffing function pointers can be an aid to clarity. (Typedeffing
other kinds of pointers is usually the opposite, IMHO; YMMV.)

--
Eric Sosman
esosman@ieee-dot-org.invalid

Keith Thompson 12-01-2010 04:01 PM

Re: understanding enum type
 
"BartC" <bc@freeuk.com> writes:
[...]
> In the case of enums, I think their values have to be ints, so in:
>
> enum Z{zero=0};
>
> Then zero may be an int value, or an int literal (I'm not going to wade
> through 700 pages of the standard to find out exactly what). It is anyway
> not what you might expect (a Z-literal or whatever).


There's no need to wade through the whole standard, just read 6.7.2.2,
"Enumeration specifiers". It's not 100% obvious that this is going to
be under 6.7.2 "Type specifiers", which is under 6.7 "Declarations", but
looking up "enum" in the index would take you there.

(An aside: I wish that the index entries in the PDF versions of the
standard were clickable links to the referenced sections; PDF supports
that kind of thing, doesn't it?)

Given the declaration
enum Z { zero = 0 };
the identifier ``zero'' is a constant of type int. This is
admittedly somewhat counterintuitive (you might expect it to be
of type enum Z), but there are historical reasons. And in most
contexts, given C's rather promiscuous implicit conversions, it
doesn't matter.

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"


All times are GMT. The time now is 05:11 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.