473,834 Members | 1,801 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

A more verbose discussion of const and conversions... (part 2)

Heh, spelled out in black and white even :) Const is useles...

do NOT follow the path of considering any data consatant, because in
time, you will have references to it that C does not handle, and you'll
be left with just noisy compiler warnings and confusion.

if you start a project with all char *, and char ** and even char ***,
if you begin at the low level weeding out references of 'passing const
char * to char * ( such as myfunction ( char * blah ); yourfunction(
void ) { myfunction( "blasdfaklj sdf" ); } )

And I guarantee that the declared references to the data are ....

7.1.4 Use of library functions
1 Each of the following statements applies unless explicitly stated
otherwise in the detailed descriptions that follow: If an argument to a
function has an invalid value (such as a value outside the domain of the
function, or a pointer outside the address space of the program,
or a null pointer, or a <BOLD>pointer to non-modifiable storage when the
corresponding parameter is not const-qualified)</BOLD>or a type (after
promotion) not expected by a function with variable number of arguments,
the behavior is undefined.

So I have decided I want to stick to defined behaviors, and allow users
the lattitutude to do what they want.

( this is mostly just notes and pulling relavent chunks, but then
reading and comprehending are two different things, if const is
literally implemented, then there are still inconsitancies)

-----

typedef const char a;
typedef const a * b; // Error! E1060: Invalid type

?
// there was a portion of the standard that says no matter how many
times the qualifier appears for a type, that it makes no difference.
-----

char const * const * gvar;
char const * cvar;

gvar = &cvar; // OK: 'char const **' conversion to 'char const *const
*'
Following the standard, why does the above not fail due to
6.7.5.1.2(below )?
-----

Full test results are at the end... I don't get it... somehow I think
that there's a special case somewhere that isn't right, and/or should be
extended....

------------------------------------------------------------
------------------------------------------------------------
Okay, really, I give up. I fixed everything so it doesn't fail
compiling with C++, for which warnings became errors. Certainly one
direction is okay and deserves not a warning.

I was really just cleaning warnings, and find I keep changing this
definitino of variable, and now, nothing is happy cause at one point or
another there are edge conditions where const-qualified code meets
nonqualified code, and it's always ugly, except in a couple simple
cases, which are 'byproducts' of .. [6.3.2.1-2], or [6.5.4.4] I
guess...



6.5.16.1 Simple assignment
..1 One of the following shall hold: [ 93) The asymmetric appearance of
these constraints with respect to type qualifiers is due to the
conversion (specified in 6.3.2.1[.2]) that changes lvalues to ''the
value of the expression'' which removes any type qualifiers from the
type category of the expression. ]

- the left operand has qualified or unqualified arithmetic type and the
right has arithmetic type;
- the left operand has a qualified or unqualified version of a structure
or union type compatible with the type of the right;
- both operands are pointers to qualified or unqualified versions of
compatible types, and the type pointed to by the left has all the
qualifiers of the type pointed to by the right;
- one operand is a pointer to an object or incomplete type and the other
is a pointer to a qualified or unqualified version of void, and the type
pointed to by the left has all the qualifiers of the type pointed to by
the right;
- the left operand is a pointer and the right is a null pointer
constant; or
- the left operand has type _Bool and the right is a pointer.

..6 EXAMPLE 3 Consider the fragment:
const char **cpp;
char *p;
const char c = 'A';
cpp = &p; // constraint violation
*cpp = &c; // valid
*p = 0; // valid
The first assignment is unsafe because it would allow the following
valid code to attempt to change the value of the const object c.
Okay and even the other fragment I wrote just now about storing another
const char * in place of an argument results in perhaps a rom data point
that the subsequent code could expect to modify, but cannot.
But if we modify the above frament slightly

const char *const*cpp; // <-- add additional const.
char *p;
const char c = 'A';
cpp = &p; // constraint violation
*cpp = &c; // valid //<-- invalid, cannot modify const *ERROR*
*p = 0; // valid //

Also stops the replacement of (char *) elements with (const char *)
which may indeed be read only.
const char *const*cpp; // <-- add additional const.
char * *p;
cpp=p; // without
6.3.2 Other operands
6.3.2.1 Lvalues, arrays, and function designators
1 Anlvalue is an expression with an object type or an incomplete type
other than void;53) if an lvalue does not designate an object when it is
evaluated, the behavior is undefined. When an object is said to have a
particular type, the type is specified by the lvalue used to
designate the object. A modifiable lvalue is an lvalue that does not
have array type, does not have an incomplete type, does not have a
const-qualified type, and if it is a structure or union, does not have
any member (including, recursively, any member or element of all
contained aggregates or unions) with a const-qualified type.

2 Except when it is the operand of the sizeof operator, the unary &
operator, the ++ operator, the -- operator, or the left operand of the .
operator or an assignment operator, an lvalue that does not have array
type is converted to the value stored in the designated object (and is
no longer an lvalue). If the lvalue has qualified type, the value has
the unqualified version of the type of the lvalue; otherwise, the value
has the type of the lvalue. If the lvalue has an incomplete type and
does not have array type, the behavior is undefined.

---
My notes so if none of these...

sizeof(lvalue)
&lvalue
lvalue++
lvalue--
lvelue=
lvalue[]
lvalue.

then copy data within lvalue, and make it a value, which is not an
lvalue, that is not const.)
the value result is non qualified.

6.5.4.4
note 85) A cast does not yield an lvalue. Thus, a cast to a qualified
type has the same effect as a cast to the unqualified version of the
type.

----------------------

Back research As I read I began to wonder if they hadn't defined a
smaller box for themselves...

6.7.5.1 Pointer declarators
Semantics
1 If, in the declaration ''T D1'', D1 has the form
* type-qualifier-listopt D
and the type specified for ident in the declaration ''T D'' is
''derived-declarator-type-list
T'', then the type specified for ident is ''derived-declarator-type-list
type-qualifier-list
pointer to T''. For each type qualifier in the list, ident is a
so-qualified pointer.
[6.7.5.1.2] For two pointer types to be compatible, both shall be
identically qualified and both shall
be pointers to compatible types.

!!!!!!!!!!!!!!

that(6.7.5.1.2) would mean

int **pxia;·
int * const *pxib;·

pxib=pxia;·

should also be invalid, but it's not a warning.

int * * * * * * * zpxia;·
int * const * * * const * const * * zpxib;·
zpxib=zpxia;·

Is invalid however....
6.7.3.9 For two qualified types to be compatible, both shall have the
identically qualified version of a compatible type; the order of type
qualifiers within a list of specifiers or qualifiers does not affect the
specified type.
------
verbatum check for types, both with bare type and progressive
derivations<?of type.

void junkx( void )
{
const char aconst;
char avar;
char * const bconst;
char *bvar;

char const * const cconst;
char const * cvar;

char * * const dconst;
char const * * const econst;
char * const * const fconst;
char const * const * const gconst;

char * *dvar;
char const * * evar;
char * const *fvar;
char const * const * gvar;

char * * * hvar;
char const * * * ivar;
char * const * *jvar;
char const * const * * kvar;
char * * const * lvar;
char const * * const * mvar;
char * const * const *nvar;
char const * const * const * ovar;

//bconst = &aconst;
//bconst = &avar;
bvar = &aconst;
bvar = &avar; // invalid char const * -char *

bvar = cconst; // invalid char const * -char *
bvar = cvar; // invalid char const * -char *

cvar = &aconst;
cvar = &avar;

cvar = bconst;
cvar = bvar;

dvar = &bvar; // OK: 'char **' -'char **'
dvar = &bconst; // 'char *const *' -'char **'
dvar = &cvar; // 'char const **' -'char **'
dvar = &cconst; // 'char const *const *' -'char **'

evar = &bvar; // 'char **' -'char const **'
evar = &bconst; // 'char *const *' -'char const **'
evar = &cvar; // OK: 'char const **' -'char const **'
evar = &cconst; // 'char const *const *' -'char const **'

fvar = &bvar; // OK: 'char const **' -'char *const *'
fvar = &bconst; // OK: 'char *const *' -'char *const *'
fvar = &cvar; // 'char const **' -'char *const *'
fvar = &cconst; // 'char const *const *' -'char *const *'

gvar = &bvar; // 'char const **' -'char const *const *'
gvar = &bconst; // 'char *const *' -'char const *const *'
gvar = &cvar; // OK: 'char const **' -'char const *const *'
gvar = &cconst; // OK: 'char const *const *' -'char const *const
*'
hvar = &dvar; // OK: 'char ***' -'char ***'
hvar = &dconst; // 'char **const *' -'char ***'
hvar = &evar; // 'char const ***' -'char ***'
hvar = &econst; // 'char const **const *' -'char ***'
hvar = &fvar; // 'char *const **' -'char ***'
hvar = &fconst; // 'char const **const *' -'char ***'
hvar = &gvar; // 'char const *const **' -'char ***'
hvar = &gconst; // 'char const *const *const *' -'char ***'

ivar = &dvar; // 'char ***' -'char const ***'
ivar = &dconst; // 'char **const *' -'char const ***'
ivar = &evar; // OK:'char const ***' -'char const ***'
ivar = &econst; // 'char const **const *' -'char const ***'
ivar = &fvar; // 'char *const **' -'char const ***'
ivar = &fconst; // 'char const **const *' -'char const ***'
ivar = &gvar; // 'char const *const **' -'char const ***'
ivar = &gconst; // 'char const *const *const *' -'char const ***'

jvar = &dvar; // 'char ***' -'char *const **'
jvar = &dconst; // 'char **const *' -'char *const **'
jvar = &evar; // 'char const ***' -'char *const **'
jvar = &econst; // 'char const **const *' -'char *const **'
jvar = &fvar; // OK'char *const **' -'char *const **'
jvar = &fconst; // 'char const **const *' -'char *const **'
jvar = &gvar; // 'char const *const **' -'char *const **'
jvar = &gconst; // 'char const *const *const *' -'char *const **'

kvar = &dvar; // 'char ***' -'char const * const **'
kvar = &dconst; // 'char **const *' -'char const * const **'
kvar = &evar; // 'char const ***' -'char const * const **'
kvar = &econst; // 'char const **const *' -'char const * const
**'
kvar = &fvar; // 'char *const **' -'char const * const **'
kvar = &fconst; // 'char const **const *' -'char const * const
**'
kvar = &gvar; // OK: 'char const *const **' -'char const *
const **'
kvar = &gconst; // 'char const *const *const *' -'char const *
const **'

}
typedef char a;

typedef char *b;
typedef a *b_;

typedef const char *c;
typedef const a *c_;
typedef char **d;
typedef b_ *d_;
typedef char const **e;
typedef c_ *e_;
typedef char *const *f;
typedef const b_ *f_;
typedef char const *const *g;
typedef const c_ *g_;
typedef char ***h;
typedef d_ *h_;
typedef char const ***i;
typedef e_ *i_;
typedef char *const **j;
typedef f_ *j_;
typedef char const *const **k;
typedef g_ *k_;
typedef char **const *l;
typedef const d_ *l_;
typedef char const **const *m;
typedef const e_ *m_;
typedef char *const *const *n;
typedef const f_ *n_;
typedef char const *const *const *o;
typedef const g_ *o_;

void junky( void )
{
const a aconst;
a avar;

const b bconst;
b bvar;
const c cconst;
c cvar;

const b_ _bconst;
b_ _bvar;
const c_ _cconst;
c_ _cvar;

const d dconst;
const e econst;
const f fconst;
const g gconst;

d_ dvar;
e_ evar;
f_ fvar;
g_ gvar;

h_ hvar;
i_ ivar;
j_ jvar;
k_ kvar;
l_ lvar;
m_ mvar;
n_ nvar;
o_ ovar;

bvar=_bvar;
_bvar=bvar;
bvar=_cvar; // char const * -char *
_bvar=cvar; // char const * -char *
_cvar=cvar;
cvar=_cvar;
_cvar=bvar;
cvar=_bvar;
//bconst = &aconst;
//bconst = &avar;
bvar = &aconst; // invalid 'char const *' ->'char*'
bvar = &avar; // invalid char const * -char *

bvar = cconst; // invalid char const * -char *
bvar = cvar; // invalid char const * -char *

cvar = &aconst; // okay
cvar = &avar; // okay

cvar = bconst; // okay
cvar = bvar; // okay

dvar = &bvar; // OK: 'char **' -'char **'
dvar = &bconst; // 'char *const *' -'char **'
dvar = &cvar; // 'char const **' -'char **'
dvar = &cconst; // 'char const *const *' -'char **'

evar = &bvar; // 'char **' -'char const **'
evar = &bconst; // 'char *const *' -'char const **'
evar = &cvar; // OK: 'char const **' -'char const **'
evar = &cconst; // 'char const *const *' -'char const **'

fvar = &bvar; // OK: 'char const **' -'char *const *'
fvar = &bconst; // OK: 'char *const *' -'char *const *'
fvar = &cvar; // 'char const **' -'char *const *'
fvar = &cconst; // 'char const *const *' -'char *const *'

gvar = &bvar; // 'char const **' -'char const *const *'
gvar = &bconst; // 'char *const *' -'char const *const *'
gvar = &cvar; // OK: 'char const **' -'char const *const *'
gvar = &cconst; // OK: 'char const *const *' -'char const *const
*'
hvar = &dvar; // OK: 'char ***' -'char ***'
hvar = &dconst; // 'char **const *' -'char ***'
hvar = &evar; // 'char const ***' -'char ***'
hvar = &econst; // 'char const **const *' -'char ***'
hvar = &fvar; // 'char *const **' -'char ***'
hvar = &fconst; // 'char const **const *' -'char ***'
hvar = &gvar; // 'char const *const **' -'char ***'
hvar = &gconst; // 'char const *const *const *' -'char ***'

ivar = &dvar; // 'char ***' -'char const ***'
ivar = &dconst; // 'char **const *' -'char const ***'
ivar = &evar; // OK:'char const ***' -'char const ***'
ivar = &econst; // 'char const **const *' -'char const ***'
ivar = &fvar; // 'char *const **' -'char const ***'
ivar = &fconst; // 'char const **const *' -'char const ***'
ivar = &gvar; // 'char const *const **' -'char const ***'
ivar = &gconst; // 'char const *const *const *' -'char const ***'

jvar = &dvar; // 'char ***' -'char *const **'
jvar = &dconst; // 'char **const *' -'char *const **'
jvar = &evar; // 'char const ***' -'char *const **'
jvar = &econst; // 'char const **const *' -'char *const **'
jvar = &fvar; // OK'char *const **' -'char *const **'
jvar = &fconst; // 'char const **const *' -'char *const **'
jvar = &gvar; // 'char const *const **' -'char *const **'
jvar = &gconst; // 'char const *const *const *' -'char *const **'

kvar = &dvar; // 'char ***' -'char const * const **'
kvar = &dconst; // 'char **const *' -'char const * const **'
kvar = &evar; // 'char const ***' -'char const * const **'
kvar = &econst; // 'char const **const *' -'char const * const
**'
kvar = &fvar; // 'char *const **' -'char const * const **'
kvar = &fconst; // 'char const **const *' -'char const * const
**'
kvar = &gvar; // OK: 'char const *const **' -'char const * const
**'
kvar = &gconst; // 'char const *const *const *' -'char const *
const **'
}
------

Michal Necasek wrote:
J Decker wrote:
>C99 is a standard written by people with an agenda to pass their
particular instance, and if realization's never changed, C90 or K&R
would still suffice today.
>>
Fine. Find me the relevant text that allows the assignment in C90.
You obviously won't find it in K&R because it didn't have 'const' at
all.
>
>So all in all, you're telling me that 'const' does not mean: a public
declaration that the variable or parameter will not be modified from
this variable.
>>
The semantics of the 'const' type qualifier in C are defined by the C
language standard.
>

Michal
Nov 30 '06 #1
0 1878

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

Similar topics

5
5070
by: Bolin | last post by:
Hi all, A question about smart pointers of constant objects. The problem is to convert from Ptr<T> to Ptr<const T>. I have look up and seen some answers to this question, but I guess I am too stupid to understand and make them work. E.g. I have read that boost's smart pointers are able to do this convertion, but the following code doesn't compile (VC++6.0):
19
2811
by: Christian Engström | last post by:
If you have a function that returns something by value, the gcc compiler (version 3.2.3 on Windows XP with MinGW) converts the returned value from the type you specify in the code, to the const version of that type. Is this a bug that is specific to gcc, or is it a flaw in the language specification that gcc diligently implements? For example, the below program produces the output Constant Mutable
6
8271
by: bob_jenkins | last post by:
{ const void *p; (void)memset((void *)p, ' ', (size_t)10); } Should this call to memset() be legal? Memset is of type void *memset(void *, unsigned char, size_t) Also, (void *) is the generic pointer type. My real question is, is (void *) such a generic pointer type that it
24
2355
by: kevin.hall | last post by:
Is char** (or char*) implicitly convertible to 'const char * const *'? I couldn't find anything about it in the standard. MSVS 8.0 allows this. I'm curious if I'll run into trouble with other compilers like GCC though. Many thanks! - Kevin
2
2020
by: Lorenzo Castelli | last post by:
This is an old problem of mine. Basically I have an abstract base class which represents a generic iterator over a collection of elements, and various derived classes that implement the traversing on specific data structures. For each iterator I want to be able to specify the four possible const combinations, corresponding to the various void* for pointers, with the possibility to perform conversions from non-const to const just like...
3
4074
by: mast2as | last post by:
In the same vein as the topic that I started on exception handling ;-) .... If I have read (not all of them though) the documents that you guys pointed me to, the try/throw/catch mechanism should really be kept for exception handling (basically errors whevere they are critical or not). Now, while I am developing this application, so far I used std::cout quite a lot to check that the code was doing the right thing (writing out to the...
8
4101
by: Michael Safyan | last post by:
Dear members of comp.lang.c++, I am a little bit confused about the differences between constant references and values. I understand that it is faster to use a constant reference ("const T&") than a value ("T") since the former does not require copying whereas the latter does, is that correct? Also, I un derstand that "const T&" allows for polymorphism whereas "T" will generate code cuttting. On the former points, I am fairly confident......
10
3455
by: JurgenvonOerthel | last post by:
Consider the classes Base, Derived1 and Derived2. Both Derived1 and Derived2 derive publicly from Base. Given a 'const Base &input' I want to initialize a 'const Derived1 &output'. If the dynamic type of 'input' is Derived1, then 'output' should become a reference to 'input'. Otherwise 'output' should become a reference to the (temporary) result of the member function 'input.to_der1()' which returns a Derived1 object by value.
2
1940
by: t | last post by:
Lippman's C++ Primer, 4th ed., p562, dicussion of protected members seems to be wrong, unless I am misinterpreting things. He says: "A derived class object may access the protected members of its base class only through a derived object. The derived class has no special access to the protected members of base type objects." He gives the following example: =========================================================
0
9799
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
10799
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
10554
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 Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
10224
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
7761
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6960
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 then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5629
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 last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5799
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4428
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system

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.