C doubt(const variable)

  • Thread starter sangeeta chowdhary
  • Start date
S

sangeeta chowdhary

#include<stdio.h>
#include<string.h>

union employee
{
char name[15];
int age;
float salary;
};

const union employee e1;
int main()
{
e1.age=10; //error in gcc
e1.name="A"; //error in gcc
strcpy(e1.name,"A"); //warning in gcc
fun(&e1);
printf("%s %d %f\n",e1.name,e1.age,e1.salary);
return 0;
}

int fun(const union employee *e)
{
strcpy(e->name,"B");
return 0;
}

here e1 is const,then why line strcpy(e1.name,"A"); is just showing
warning in gcc,why not error as i am trying to change const
parameter.
Whereas line e1.name="A"; is an error.
 
J

Jens Thoms Toerring

sangeeta chowdhary said:
#include<stdio.h>
#include<string.h>
union employee
{
char name[15];
int age;
float salary;
};
const union employee e1;
int main()
{
e1.age=10; //error in gcc
e1.name="A"; //error in gcc
strcpy(e1.name,"A"); //warning in gcc
fun(&e1);
printf("%s %d %f\n",e1.name,e1.age,e1.salary);
return 0;
}
int fun(const union employee *e)
{
strcpy(e->name,"B");
return 0;
}
here e1 is const,then why line strcpy(e1.name,"A"); is just showing
warning in gcc,why not error as i am trying to change const
parameter.

Because you don't change e1 at that line, you call a func-
tion, strcpy(), which may or may not change e1, but the com-
piler doesn't know what strcpy() is going to do. All it
knows about strcpy() is that it expects a non-constant
pointer as its first argument (due to the declaration in
<string.h>) while you pass it a const qualified pointer.
And that's all the conpiler can warn you about at that
stage.

Of course, it would have been possible to have the compiler
consider it to be an error when passing a const qualified
object (pointer_) to a function that expects a mutable object
(pointer), but that's not how it works in C. That's one of
the differen- ces to C++ with it's more strict type system.
Whereas line e1.name="A"; is an error.

Yes, because at that line you actually modify e1 and don't
just pass its address to a function. So the compiler can
spot at this place that you're doing something forbidden.

Regards, Jens
 
B

Ben Bacarisse

sangeeta chowdhary said:
#include<stdio.h>
#include<string.h>

union employee
{
char name[15];
int age;
float salary;
};

Why is the a union? A struct seems to be what you want.
const union employee e1;
int main()
{
e1.age=10; //error in gcc
e1.name="A"; //error in gcc
strcpy(e1.name,"A"); //warning in gcc
fun(&e1);
printf("%s %d %f\n",e1.name,e1.age,e1.salary);

I think you've misunderstood what a union is.
return 0;
}

int fun(const union employee *e)
{
strcpy(e->name,"B");
return 0;
}

here e1 is const,then why line strcpy(e1.name,"A"); is just showing
warning in gcc,why not error as i am trying to change const
parameter.

I would try not to worry about these sort of distinctions.
Historically, pointer conversions have been used to sidestep the
language's type system so I image that gcc found it caused too much
trouble to make the error a "hard" one that stop the compilation. The C
standard requires that a diagnostic be issued for the strcpy call but
that is all.

While you are learning C, it really helps to turn on a lot of gcc's
warnings and to take all of them seriously. Some can be safely ignored,
but only once you know what is being complained about and why it is safe
in the particular case you are considering.
Whereas line e1.name="A"; is an error.

This would be an error even if e1 were not const because arrays can't be
assigned to in C.
 
J

Jens Thoms Toerring

Yes, because at that line you actually modify e1 and don't
just pass its address to a function. So the compiler can
spot at this place that you're doing something forbidden.

Uups, I didn't read carefully enough and assumed that you
meant the line

and not the assignment to e1.name which, as Ben pointed out,
is a syntax error and not related to the const-ness of e1.

Regards, Jens
 
D

Denis McMahon

union employee
{
char name[15];
int age;
float salary;
};

This should probably be a struct, not a union!

I suggest you review your course material for the difference between
union and struct again.

Rgds

Denis McMahon
 
B

Ben Bacarisse

sangeeta chowdhary said:
#include<stdio.h>
#include<string.h>
union employee
{
char name[15];
int age;
float salary;
};
const union employee e1;
int main()
{
e1.age=10; //error in gcc
e1.name="A"; //error in gcc
strcpy(e1.name,"A"); //warning in gcc
fun(&e1);
printf("%s %d %f\n",e1.name,e1.age,e1.salary);
return 0;
}
int fun(const union employee *e)
{
strcpy(e->name,"B");
return 0;
}
here e1 is const,then why line strcpy(e1.name,"A"); is just showing
warning in gcc,why not error as i am trying to change const
parameter.

Because you don't change e1 at that line, you call a func-
tion, strcpy(), which may or may not change e1, but the com-
piler doesn't know what strcpy() is going to do. All it
knows about strcpy() is that it expects a non-constant
pointer as its first argument (due to the declaration in
<string.h>) while you pass it a const qualified pointer.

The pointer is not const qualified and strcpy does not expect a
"non-constant pointer". Now, I know what you mean, but a learner may
get confused. strcpy expects a pointer to non-const qualified char and
it is being given a pointer to a const qualified type -- specifically
const char *.

To the OP: there is a difference between a const qualified pointer to a
type T (T * const) and a pointer to const qualified T (const T *).
And that's all the conpiler can warn you about at that
stage.

Of course, it would have been possible to have the compiler
consider it to be an error when passing a const qualified
object (pointer_)

See above.
to a function that expects a mutable object
(pointer), but that's not how it works in C.

Well, in a way it is an error of sorts -- it must be diagnosed since
const char * and char * are not "assignment compatible" (that's a term I
use to combine the rules of type compatibility with the assignment rules
for pointers that govern parameter passing).

One reason for it not stopping the compile might be that the conversion
itself is not always wrong. If we add a cast, the compiler must
permit this:

#include <string.h>

char s[] = "abc";

void foo(const char *arg)
{
strcpy((char *)arg, "def");
}
That's one of
the differen- ces to C++ with it's more strict type system.


Yes, because at that line you actually modify e1 and don't
just pass its address to a function. So the compiler can
spot at this place that you're doing something forbidden.

In some ways the line does not modify e1 because e1.name is an array.
The assignment is a constraint violation even with out the const
qualifier. If the compiler complains about the constness of e1, that's
fine, but it's just masking another error.
 
J

Jens Thoms Toerring

Ben Bacarisse said:
sangeeta chowdhary said:
#include<stdio.h>
#include<string.h>
union employee
{
char name[15];
int age;
float salary;
};
const union employee e1;
int main()
{
e1.age=10; //error in gcc
e1.name="A"; //error in gcc
strcpy(e1.name,"A"); //warning in gcc
fun(&e1);
printf("%s %d %f\n",e1.name,e1.age,e1.salary);
return 0;
}
int fun(const union employee *e)
{
strcpy(e->name,"B");
return 0;
}
here e1 is const,then why line strcpy(e1.name,"A"); is just showing
warning in gcc,why not error as i am trying to change const
parameter.

Because you don't change e1 at that line, you call a func-
tion, strcpy(), which may or may not change e1, but the com-
piler doesn't know what strcpy() is going to do. All it
knows about strcpy() is that it expects a non-constant
pointer as its first argument (due to the declaration in
<string.h>) while you pass it a const qualified pointer.
The pointer is not const qualified and strcpy does not expect a
"non-constant pointer". Now, I know what you mean, but a learner may
get confused. strcpy expects a pointer to non-const qualified char and
it is being given a pointer to a const qualified type -- specifically
const char *.

Uups, yes:-(
To the OP: there is a difference between a const qualified pointer to a
type T (T * const) and a pointer to const qualified T (const T *).

Ben, thank you for the corrections!

Best regards, Jens
 
S

sangeeta chowdhary

#include<stdio.h>
#include<string.h>

union employee
{
  char name[15];
  int age;
  float salary;

};

const union employee e1;
int main()
{
  e1.age=10;  //error in gcc
  e1.name="A";  //error in gcc
  strcpy(e1.name,"A");  //warning in gcc
  fun(&e1);
  printf("%s %d %f\n",e1.name,e1.age,e1.salary);
  return 0;

}

int fun(const union employee *e)
{
  strcpy(e->name,"B");
  return 0;

}

here e1 is const,then why line  strcpy(e1.name,"A"); is just showing
warning in gcc,why not error as i am trying to change const
parameter.
Whereas line  e1.name="A"; is an error.

According to you,a const variable can be changed inside function?
 
I

Ian Collins

#include<stdio.h>
#include<string.h>

union employee
{
char name[15];
int age;
float salary;

};

const union employee e1;
int main()
{
e1.age=10; //error in gcc
e1.name="A"; //error in gcc
strcpy(e1.name,"A"); //warning in gcc
fun(&e1);
printf("%s %d %f\n",e1.name,e1.age,e1.salary);
return 0;

}

int fun(const union employee *e)
{
strcpy(e->name,"B");
return 0;

}

here e1 is const,then why line strcpy(e1.name,"A"); is just showing
warning in gcc,why not error as i am trying to change const
parameter.
Whereas line e1.name="A"; is an error.

According to you,a const variable can be changed inside function?

According to who?
 
D

David Thompson

#include<stdio.h>
#include<string.h>

union employee
{
char name[15];
int age;
float salary;
};
As already noted it doesn't make sense for these to be a union, but
I'm guessing this was a teaching example and someone liked the joke.
Also, it doesn't matter at your early stage, but in general it's a bad
idea to use floating-point (and especially float=single) for decimal
money amounts; if someday you reach the point of actually writing
financial/business software in C, remember that. Of course,
it's plausible that this 'application' is for a hypothetical firm that
makes all salaries be integer dollars -- or, heck, integer yen.
In the absence of collective bargaining or government regulation,
I can easily imagine that being popular with people.
const union employee e1;
int main()
{
e1.age=10; //error in gcc
e1.name="A"; //error in gcc
strcpy(e1.name,"A"); //warning in gcc
here e1 is const,then why line strcpy(e1.name,"A"); is just showing
warning in gcc,why not error as i am trying to change const
parameter.
Whereas line e1.name="A"; is an error.

Both of these -- assigning directly to a field like e1.age, or calling
a routine that takes a pointer-to-nonconst like strcpy(e1.name,) --
are constraint violations. The standard requires a diagnostic; either
an error or warning is fine as far as the standard is concerned.

Although I can't speak for the gcc implementors, a logical reason for
them to have made these different is that e1.fld=x is always wrong,
but func_of_nonconst(&e1.fld) is only wrong if the function actually
stores through that pointer. Before C89 there was no 'const', so all
code written before then, plus much code written after then by people
who learned before, or didn't care about const, or even disliked* it,
doesn't say const but is often actually okay, and historically it's
been the 'bias' of the C community for compilers to err toward the
side of trusting the programmer and accepting possibly-bad code.

OTOH in this case strcpy is (and must be) a standard-library function,
which the compiler can know about -- and gcc does know about some
'builtins' including strcpy for other purposes -- so it could have
realized this case is definitely wrong. I guess they figured that the
warning is already there and the extra effort to make it an error in
this case isn't worth it.

Note that for gcc you can make (all) warnings fatal just by using the
flag -Werror, if you want. Some other compilers have functionally
similar options; this is not an uncommon desire. Some shops use it on
checkin as a simple way to enforce a 'no warnings' rule.

* In particular, if after writing (or just specifying) (some of) your
code you decide to make a reference in a lower level routine const
that wasn't before, you usually must change some higher level ones to
follow suit -- sometimes a large number of them. This is disparaged as
'const poisoning' by people who consider it not worth the trouble, and
I for one don't say they're always wrong.

Note that e1.name = "A" violates another constraint as well; you can't
assign to any array, even one that isn't const.
fun(&e1);
printf("%s %d %f\n",e1.name,e1.age,e1.salary);
return 0;
}

int fun(const union employee *e)
{
strcpy(e->name,"B");
return 0;
}
This function wasn't prototype-declared at the point you called it,
which is why the compiler isn't required to (and didn't) diagnose this
equally-wrong access. If you move this function before main(), or put
a prototype declaration of it before main() (or even inside main()
which is legal but unusual), you'll get a diagnostic.
 

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

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top