473,583 Members | 3,112 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Inability to follow good programming practice by qualifying a pointer parameter with 'const'

typedef int t_compare_func( const void *, const void *);

struct node *tree_search(st ruct node *root, const void *keyy,
t_compare_func *comp)
{
struct node *cur_item;
int result;
if (root == NULL) return NULL;
cur_item = root;
while (cur_item != NULL) {
result = (*comp)(cur_ite m->key, keyy);
if (result == 0)
break;
else if (result > 0)
cur_item = cur_item->left;
else
cur_item = cur_item->right;
}
return cur_item;
}
Here, I traverse the tree to find a node whose key member is the same
as keyy. And the node found is returned. Nothing in the tree is ever
modified. So naturally I would like to const-ify root (in the param
list). But then I am forced to also const-ify cur_item. And the return
value also has to be const-ifed as a consequence. Now, (part of) the
tree in the calling function cannot be modified as a consequence!
Therefore I have to give up const-ifying root even though nothing in
the function modifies the tree. Can I avoid this side effect? I guess
I need to just cast root like:
cur_item = (struct node *)root;
if I decalre root as a const parameter. Right?
So I either have to give up const-ifying root or un-const-ifying root
inside the function? Any better solution?

Nov 15 '05 #1
18 1597

<hz*****@hotmai l.com> wrote in message
news:11******** *************@g 49g2000cwa.goog legroups.com...
typedef int t_compare_func( const void *, const void *);

struct node *tree_search(st ruct node *root, const void *keyy,
t_compare_func *comp)
{
struct node *cur_item;
int result;
if (root == NULL) return NULL;
cur_item = root;
while (cur_item != NULL) {
result = (*comp)(cur_ite m->key, keyy);
if (result == 0)
break;
else if (result > 0)
cur_item = cur_item->left;
else
cur_item = cur_item->right;
}
return cur_item;
}
Here, I traverse the tree to find a node whose key member is the same
as keyy. And the node found is returned. Nothing in the tree is ever
modified. So naturally I would like to const-ify root (in the param
list). But then I am forced to also const-ify cur_item. And the return
value also has to be const-ifed as a consequence. Now, (part of) the
tree in the calling function cannot be modified as a consequence!
Therefore I have to give up const-ifying root even though nothing in
the function modifies the tree. Can I avoid this side effect? I guess
I need to just cast root like:
cur_item = (struct node *)root;
if I decalre root as a const parameter. Right?
So I either have to give up const-ifying root or un-const-ifying root
inside the function? Any better solution?


You could try using recursion to search instead of iteration. That way you
never modify (or risk modifying) root. Your implementation may not allow for
recursion (ie if memory is limited). Also try looking for the C library "GNU
libavl 2.0.1" which has all tree manipulation functions.
Nov 15 '05 #2
Ok, but for the sake of discussion, let's stick with my code. Is there
any way for following good programming practice in this particular case?

Nov 15 '05 #3

<hz*****@hotmai l.com> wrote
typedef int t_compare_func( const void *, const void *);

struct node *tree_search(st ruct node *root, const void *keyy,
t_compare_func *comp)
{
struct node *cur_item;
int result;
if (root == NULL) return NULL;
cur_item = root;
while (cur_item != NULL) {
result = (*comp)(cur_ite m->key, keyy);
if (result == 0)
break;
else if (result > 0)
cur_item = cur_item->left;
else
cur_item = cur_item->right;
}
return cur_item;
}
Here, I traverse the tree to find a node whose key member is the same
as keyy. And the node found is returned. Nothing in the tree is ever
modified. So naturally I would like to const-ify root (in the param
list). But then I am forced to also const-ify cur_item. And the return
value also has to be const-ifed as a consequence. Now, (part of) the
tree in the calling function cannot be modified as a consequence!
Therefore I have to give up const-ifying root even though nothing in
the function modifies the tree. Can I avoid this side effect? I guess
I need to just cast root like:
cur_item = (struct node *)root;
if I decalre root as a const parameter. Right?
So I either have to give up const-ifying root or un-const-ifying root
inside the function? Any better solution?

I don't see your problem here.
cur_item can be a const pointer (pointer to constant data), not a pointer
which is a constant (pointer whose value may not be modified).
You can then assign a non-const address to a const pointer, but you cannot
do the other thing without a cast, which is to assign a const pointer to a
normal non-const pointer.
Nov 15 '05 #4
This restriction prevents me from following good practice. and that's
exactly what i am talking about.

Nov 15 '05 #5
<hz*****@hotmai l.com> wrote in message
news:11******** *************@g 49g2000cwa.goog legroups.com...
[snip]
Here, I traverse the tree to find a node whose key member is the same
as keyy. And the node found is returned. Nothing in the tree is ever
modified. So naturally I would like to const-ify root (in the param
list). But then I am forced to also const-ify cur_item. And the return
value also has to be const-ifed as a consequence. Now, (part of) the
tree in the calling function cannot be modified as a consequence!
If I understand correctly, this is equivalent to (for example) strchr(),
which doesn't modify its string argument but of course the caller may like
to write through the returned pointer (after checking it isn't NULL, of
course).
Therefore I have to give up const-ifying root even though nothing in
the function modifies the tree. Can I avoid this side effect? I guess
I need to just cast root like:
cur_item = (struct node *)root;
if I decalre root as a const parameter. Right?
So I either have to give up const-ifying root or un-const-ifying root
inside the function? Any better solution?


IMHO, the best solution is to declare the root and cur_item pointers const,
and cast cur_item at the last possible moment - the return statement.

Alex
Nov 15 '05 #6
>IMHO, the best solution is to declare the root and cur_item pointers const,
and cast cur_item at the last possible moment - the return statement.
Isn't that kind of casting is considered bad programming practice in
general?

Nov 15 '05 #7

hz*****@hotmail .com wrote:
IMHO, the best solution is to declare the root and cur_item pointers const,

and cast cur_item at the last possible moment - the return statement.
Isn't that kind of casting is considered bad programming practice in
general?

I see your point.

This is a typical problem of const qualifying a parameter. Even Ritchie
(K&R) had expressed his consern on a similar issue.
http://www.lysator.liu.se/c/dmr-on-noalias.html.

-suresh

Nov 15 '05 #8
Just for the record, according to
http://lxr.linux.no/source/lib/string.c#L254. strchr() is defined as
follows:
char * strchr(const char * s, int c)
{
for(; *s != (char) c; ++s)
if (*s == '\0')
return NULL;
return (char *) s;
}
Apparently the benefit of qualifying *s as const is considered as
outweighing the drawback of casting away the const-ness of s. Thanks.

Nov 15 '05 #9
hz*****@hotmail .com wrote:
typedef int t_compare_func( const void *, const void *);

struct node *tree_search(st ruct node *root, const void *keyy,
t_compare_func *comp)
{
struct node *cur_item;
int result;
if (root == NULL) return NULL;
cur_item = root;
while (cur_item != NULL) {
result = (*comp)(cur_ite m->key, keyy);
if (result == 0)
break;
else if (result > 0)
cur_item = cur_item->left;
else
cur_item = cur_item->right;
}
return cur_item;
}
Here, I traverse the tree to find a node whose key member is the same
as keyy. And the node found is returned. Nothing in the tree is ever
modified. So naturally I would like to const-ify root (in the param
list). But then I am forced to also const-ify cur_item. And the return
value also has to be const-ifed as a consequence. Now, (part of) the
tree in the calling function cannot be modified as a consequence!
Therefore I have to give up const-ifying root even though nothing in
the function modifies the tree. Can I avoid this side effect? I guess
I need to just cast root like:
cur_item = (struct node *)root;
if I decalre root as a const parameter. Right?
So I either have to give up const-ifying root or un-const-ifying root
inside the function? Any better solution?

You need to declare the function as returning a const struct node *
value (i.e. const struct node *tree_search(.. .)) Then it's OK to declare
root and cur_item as const.

Robert
Nov 15 '05 #10

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

Similar topics

7
2598
by: zalzon | last post by:
Is it good practice in C++ for a member function to return data or is it better that data is stored in private member variable and printed in the member function? should i be using int function1() { .... return i
110
9861
by: Mr A | last post by:
Hi! I've been thinking about passing parameteras using references instead of pointers in order to emphasize that the parameter must be an object. Exemple: void func(Objec& object); //object must be an object instead of
204
12968
by: Alexei A. Frounze | last post by:
Hi all, I have a question regarding the gcc behavior (gcc version 3.3.4). On the following test program it emits a warning: #include <stdio.h> int aInt2 = {0,1,2,4,9,16}; int aInt3 = {0,1,2,4,9};
43
2620
by: Sensei | last post by:
Hi! I'm thinking about a good programming style, pros and cons of some topics. Of course, this has nothing to do with indentation... Students are now java-dependent (too bad) and I need some serious motivations for many issues... I hope you can help me :) I begin with the two major for now, others will come for sure! - function...
2
1658
by: mast2as | last post by:
Hi there, for a long time I've been trying to think of way of saving different data of different types using one single class (well 2 in reality, a class for the data, and 1 class for a list of data). The problem that I try to solve is the following. Imagine a class "Attribute" that needs to save multiple "Parameters" (the number of...
66
3675
by: KimmoA | last post by:
Hey! Some questions about C that have been bugging me for a while... 1) Is inline a valid C keyword or not? I was kind of surprised of not finding it in C, to be honest. My "The C Programming Language" book doesn't mention it. 2) I understand that C doesn't care about whitespace that much, but why did they make it impossible to use the...
47
5912
by: Thierry Chappuis | last post by:
Hi, I'm interested in techniques used to program in an object-oriented way using the C ANSI language. I'm studying the GObject library and Laurent Deniau's OOPC framework published on his web site at http://ldeniau.web.cern.ch/ldeniau/html/oopc/oopc.html. The approach is very instructive. I know that I could do much of this stuff with e.g....
29
3635
by: shuisheng | last post by:
Dear All, The problem of choosing pointer or reference is always confusing me. Would you please give me some suggestion on it. I appreciate your kind help. For example, I'd like to convert a string to a integer number. bool Convert(const string& str, int* pData); bool Convert(const string& str, int& data);
17
12749
by: Pietro Cerutti | last post by:
i Group, to my understanding, defining a function parameter as "const" means that the function is not going to change it. Why does the compiler says "return discards qualifiers from pointer target type" when I *access* a member of an argument defined as const? Please see the code below:
0
7815
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 effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language...
0
8168
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. ...
0
8316
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
1
7926
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...
0
6573
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, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...
0
5367
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...
0
3812
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...
1
2322
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
1
1418
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

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.