Anything wrong with this function?

K

Kai-Uwe Bux

Grizlyk said:
I want to say, that i think that compiler can do static type checking, and
const_cast<> allow to compiler to do static type checking.

If you can not take my explanation, make your own explanation, but it must
be explanaiton, something lager than "it can not because can not".

If it was clear _what_ you want explained, I would be happy to provide an
explanation to the best of my ability. However, what a compiler for a
hypothetical language where

T heap*

and

T readonly code*

is valid syntax could do at compile time or not, is something I cannot
explain. I have no such compiler and I do not know any such language.

I think pepole who are not close to standard can have own opinion about
C++ memory usage :).

Maybe. However, programs based upon those opinions detached from the
standard run a high risk of exhibiting undefined behavior.


All in all, I have the feeling that we are caught in some serious
misunderstanding about the topic. I just dropped in to explain the rational
behind the decision of the standard to treat

void f ( int );

and

void f ( const int );

as identical function signatures.

You, on the other hand, seem to be concerned with an overhaul of C++ of much
larger scale that would introduce seven(!) new keywords. I have no basis to
form any opinion on that other than that I do not really see which problem
you are trying to solve. If you put together a consistent proposal for
changing the standard with a clear exposition of the current shortcomings
of C++ that you are trying to fix, it would be much easier for me (and
presumably anybody else) to say something meaningfull about it. (If you
decide to do so, it might be good to start a new thread. It also might be
good to put it into comp.std.c++.)


Sorry for not being helpful
and best regards

Kai-Uwe Bux
 
R

Rolf Magnus

Andrey said:
Without some non-trivial analysis of the implementation of the function,
the compiler has no other choice but to push addresses onto the stack.
It has to keep in mind the possibility of user using 'const_cast' in
order to cast away the constness and modify the object the reference is
referring to.

If the int that was passed was initially declared const, the compiler
doesn't have to care about the called function's content, because in that
case, a const_cast invokes undefined behiavor.
 
A

Andrey Tarasevich

Rolf said:
If the int that was passed was initially declared const, the compiler
doesn't have to care about the called function's content, because in that
case, a const_cast invokes undefined behiavor.
...

Firstly, in general case the referent might not by declared 'const'. Modifying a
non-const object through a const reference is well defined.

Secondly, if the referent is actually declared const, it isn't const_cast that
invokes the UB. It is the actual modification attempt that does that. The
const_cast itself is prefectly well defined even in that case.
 
J

JLS

The parameter is local for the function, nobody's going to care whether that
int is const or not. In fact, the standard doesn't care either. These two
function declarations declare the same function:

void foo(int);
void foo(const int);

- Sylvester

I care.

Just because it is a small method, doesn't mean one should use good
coding practices.

It would also be better to avoid char *s at all and use a string
class.
 
J

JLS

Not this one, this is only different for the implementor of the function:
the user passes by value and keeps the original anyway. In fact, the client
code has no way to observe from the outside, whether the parameter is
modified by the function internally.


Not this one. This one would just tie down the hands of implementors of the
function. Suppose you declared

int f ( const int i );

and at some point you realize that you can speed up the computation of the
result by modifying i internally. Tough luck. That is why the standard is
well-advised to say:


Note that the situation is completely different for parameters passed by
reference.

Best

Kai-Uwe Bux

That is why you declare the method in the .h file as

void foo(int)

and define the method in the .cpp file as

void foo(const int myInt)

because as far as the interface is concerned, the const doesn't
matter. As far as the method is concerned, myInt is const.

Or do you not bother to use const on any local variable?
 
K

Kai-Uwe Bux

JLS said:
That is why you declare the method in the .h file as

void foo(int)

and define the method in the .cpp file as

void foo(const int myInt)

because as far as the interface is concerned, the const doesn't
matter. As far as the method is concerned, myInt is const.

Or do you not bother to use const on any local variable?

I think, I never had a need for a local constant. When I declare local
variables then I want to change them sometime later. But that might be due
to the kind of code I deal with. In my code, magic numbers and such are by
and large not local.

As for the parameter, I would not declare it const just because the
algorithm I choose for the implementation coincidentally happens not to
chance the parameter. In such a case, the const would not convey intend.


Best

Kai-Uwe Bux
 
G

Grizlyk

Kai-Uwe Bux said:
If it was clear _what_ you want explained, I would be happy to provide an
explanation to the best of my ability. However, what a compiler for a
hypothetical language where
...
is valid syntax could do at compile time or not, is something I cannot
explain. I have no such compiler and I do not know any such language.

Well, I repeat it again: support C++ "T heap*" or not does no metter here.
Expression "T heap*" has been used by me to make differences sharper (i see
i have not reached my goal). The question is: "const_cast<> allow compiler
to test writeable memory at compile time, not at run time", but you do not
agree with it. And I do not know why are you thinking so.

Maybe. However, programs based upon those opinions detached from the
standard run a high risk of exhibiting undefined behavior.

Sometimes to use standard successfully we need not only well know the part
of it, but be able to explain why the part looks as is. For many people it
is true, at least.

All in all, I have the feeling that we are caught in some serious
misunderstanding about the topic. I just dropped in to explain the
rational
behind the decision of the standard to treat

void f ( int );

and

void f ( const int );

as identical function signatures.

Signatures yes, maybe due to ambiguous between int and const int cast. But i
have spoken that const as parameter is useful in regardless to signatures.

You, on the other hand, seem to be concerned with an overhaul of C++ of
much
larger scale that would introduce seven(!) new keywords.

Seven? No, much more :) But this is "collections", we can not count them
separatedly as if each of them is new independent keyword. Really we need
only one "collection" for your counted "seven(!) new keywords", because if
we need explicit memory specification, we need exactly as many keywords, as
many number of types of memory we have.

I have no basis to
form any opinion on that other than that I do not really see which problem
you are trying to solve.

I know the music - "i have no problem" :). It is so easy to try delete auto
or static memory and find the problem after long time, when program has
marked as "debugged and ready to use".

Also we sometimes need to explicit control memory placement (for low-level
programming). You of course can say, that all that no need exactly to
anybody is just "implementation depended" but it is not true, because for
some different implementation, having the same hardware, we will get
non-portable code doing the same. Especially if it is so easy for compiler
to implement the portability. I agree, some of the possible improvements is
not "life or death question", we can live without it.

Sorry for not being helpful
and best regards

All ok. Thanks for your reply.
 
J

JLS

I think, I never had a need for a local constant. When I declare local
variables then I want to change them sometime later. But that might be due
to the kind of code I deal with. In my code, magic numbers and such are by
and large not local.

As for the parameter, I would not declare it const just because the
algorithm I choose for the implementation coincidentally happens not to
chance the parameter. In such a case, the const would not convey intend.

Best

Kai-Uwe Bux- Hide quoted text -

- Show quoted text -

There are other reasons to use const, other than for magic numbers.
THere is never a "need" to use const, just a high desireability.

Reasons to use const?
1. Compiler enforced, self-documenting code.
2. Allows the compiler to automatically detect some errors.

While one could argue that the use of const is of less import, the
smaller the scope of the variable, the import is never completely
eliminated. Just because you have never noticed a bug that the
compiler would have caught with the proper use of const, does not
eliminate the possibility that those bugs exist or have existed. One
type of bug that is evidently very common (as simple stupid bugs go)
is the problem with

if (a = b)

where the programmer meant comparison, rather than assignment. If a
were const, this bug shows up like a sore thumb. Of course, this isn't
the only bug that can be prevented, by the use of const, just one of
many. Other examples I've seen are when the programmer types the wrong
variable name, let's say in an assignment. Yes, it is a stupid little
bug that will eventually be discovered by unit testing or in a code
review. By why not let the compiler catch it immediately?

This is my argument for using const. Some number of bugs will be
caught using const. It makes the code clearer and more understandable.
There is no down side, so why not use it?
 
G

Grizlyk

Rolf said:
If the int that was passed was initially declared const, the compiler
doesn't have to care about the called function's content, because in that
case, a const_cast invokes undefined behiavor.

Maybe, if compiler do not inline function, it could mark function using
const_cast<> for its const referenced parameter as requested the reference
to be placed in writable memory, and at link stage linker will detect the
usage of readonly memory in const_cast<>. It is better than "undefined
behaviour". Consider

- 1.cpp -
void foo ( const int &); // foo$const_int&$

void test()
{
//readonly segment
static const int i=0;
foo(i); // foo$const_int&%readonly$


//writable segment
static int k=0;
foo(i); // foo$const_int&%writable$
}
- 1.cpp -

- 2.cpp -
void foo ( const int & p) // foo$const_int&%writable$
{
int &tmp=const_cast<int&>(p);
}
- 2.cpp -

- 3.cpp -
void foo ( const int & ) // foo$const_int&%readonly$
{
}
- 3.cpp -

Linking 1.cpp + 2.cpp we will get link time error, because external
"foo$const_int&%readonly$" was not found.

Linking 1.cpp + 2.cpp + 3.cpp we will get link time error, because
"foo$const_int&%readonly$" and "foo$const_int&%writable$" can not be public
simultaneously.

Linking 1.cpp + 3.cpp we get sucsessful link, because public
"foo$const_int&%readonly$" can be used as external
"foo$const_int&%writable$".
 
T

Thomas J. Gritzan

Grizlyk said:
Well, I repeat it again: support C++ "T heap*" or not does no metter here.
Expression "T heap*" has been used by me to make differences sharper (i see
i have not reached my goal). The question is: "const_cast<> allow compiler
to test writeable memory at compile time, not at run time", but you do not
agree with it. And I do not know why are you thinking so.

void somefunction(const char* cstr)
{
char* str = const_cast<char*>(cstr);
// write to str
}

void test()
{
char arr[] = "string1";

somefunction(arr);
somefunction("string2");
}

The compiler /cannot/ test at compile time, if memory is readonly or not.
It /may/ work in one compilation unit, but it won't work across compilation
units or from a library.

The compiler can only warn in the cases it sees the function body, but why
should it? The programmer is supposed to know when he is allowed to use a
const_cast.
 
G

Grizlyk

Thomas said:
void somefunction(const char* cstr)
{
char* str = const_cast<char*>(cstr);
// write to str
}

void test()
{
char arr[] = "string1";

somefunction(arr);
somefunction("string2");
}

The compiler /cannot/ test at compile time, if memory is readonly or not.
It /may/ work in one compilation unit, but it won't work across
compilation
units or from a library.

The compiler can only warn in the cases it sees the function body, but why
should it? The programmer is supposed to know when he is allowed to use a
const_cast.

Agree, but can at link time:

[quote news:[email protected]]
- 1.cpp -
void foo ( const int &); // foo$const_int&$

void test()
{
//readonly segment
static const int i=0;
foo(i); // foo$const_int&%readonly$

//writable segment
static int k=0;
foo(i); // foo$const_int&%writable$
}
- 1.cpp -
[/quote]
 
T

Thomas J. Gritzan

Grizlyk said:
Thomas said:
The compiler /cannot/ test at compile time, if memory is readonly or not.
It /may/ work in one compilation unit, but it won't work across
compilation
units or from a library.

Agree, but can at link time:

[quote news:[email protected]]
- 1.cpp -
void foo ( const int &); // foo$const_int&$

void test()
{
//readonly segment
static const int i=0;
foo(i); // foo$const_int&%readonly$

//writable segment
static int k=0;
foo(i); // foo$const_int&%writable$
}
- 1.cpp -
[/QUOTE]

So the compiler/linker should track every pointer where it is from?
Thats not possible at compile time:

void test()
{
std::vector<const int*> intlist;

fill_list(intlist);

for (size_t i = 0; i < intlist.size(); i++)
foo(intlist);
}

Why should they do that anyway? Why have /const/ and /the_true_const/ if
you can have the same with const and non-const?
 
K

Kai-Uwe Bux

JLS said:
Reasons to use const?
1. Compiler enforced, self-documenting code.
2. Allows the compiler to automatically detect some errors.

While one could argue that the use of const is of less import, the
smaller the scope of the variable, the import is never completely
eliminated. Just because you have never noticed a bug that the
compiler would have caught with the proper use of const, does not
eliminate the possibility that those bugs exist or have existed. One
type of bug that is evidently very common (as simple stupid bugs go)
is the problem with

if (a = b)

where the programmer meant comparison, rather than assignment. If a
were const, this bug shows up like a sore thumb. Of course, this isn't
the only bug that can be prevented, by the use of const, just one of
many. Other examples I've seen are when the programmer types the wrong
variable name, let's say in an assignment. Yes, it is a stupid little
bug that will eventually be discovered by unit testing or in a code
review. By why not let the compiler catch it immediately?

In my code, local variables just tend to be modified along the way. If they
were not, there was little reasons to declare them. (One prominent counter
example is mentioned below). That's why they tend to be non-const. The tiny
fraction of those that could be const because they happen not to change
will not catch significantly many errors.

I want the code to convey intent. When I declare a local variable, my intent
is in more than 99% of all cases to modify it later.
This is my argument for using const. Some number of bugs will be
caught using const. It makes the code clearer and more understandable.
There is no down side, so why not use it?

Quick question: would you do

template < typename T >
void swap ( T & lhs, T & rhs ) {
T dummy ( lhs );
lhs = rhs;
rhs = dummy;
}

or

template < typename T >
void swap ( T & lhs, T & rhs ) {
const T dummy ( lhs );
lhs = rhs;
rhs = dummy;
}


Best

Kai-Uwe Bux
 
G

Gavin Deane

Maybe, if compiler do not inline function, it could mark function using
const_cast<> for its const referenced parameter as requested the reference
to be placed in writable memory, and at link stage linker will detect the
usage of readonly memory in const_cast<>. It is better than "undefined
behaviour".

I've read several of your posts recently and I think it might help
others to understand your point of view if you could distinguish
between two different situations:
1. Occasions when you are describing how you believe C++ works.
2. Occasions when you are describing how you feel some hypothetical
future version of C++ ought to work.

For the first, there is an indisputable definition in the C++ standard
and there are enough people here familiar with it that if you make a
mistake you will be corrected.
For the second, you may well find some interest here, although
comp.std.c++ is probably be more topical. But clearly in this case
there is no concept of "correcting" what you say because there is no
concrete definition of some hypothetical future version of C++.

I have responded to posts of yours in the past by attempting to
correct an apparent misunderstanding of C++ on your part, only to
discover later in the discussion that you appear to be talking not
about C++, but about some hypothetical future version of the language.
And I get the impression that some others may have found themselves in
the same situation. I think this could be avoided if you distinguish
between the two situations I've described.

Gavin Deane
 
G

Grizlyk

Thomas said:
The compiler /cannot/ test at compile time, if memory is readonly or
not.
It /may/ work in one compilation unit, but it won't work across
compilation units or from a library.

Agree, but can at link time:

[quote news:[email protected]]
- 1.cpp -
void foo ( const int &); // foo$const_int&$

void test()
{
//readonly segment
static const int i=0;
foo(i); // foo$const_int&%readonly$

//writable segment
static int k=0;
foo(i); // foo$const_int&%writable$
}
- 1.cpp -

So the compiler/linker should track every pointer where it is from?
Thats not possible at compile time:[/QUOTE]

Not of course, do you see the message by link? Compiler for each used
variable must create compile time list of properties, and store: "access",
"write" and "const_cast<>" attempts. And compiler alredy do it (excluding
"const_cast<>"), messsages "variable declared but never used" or "possible
usage of unassigned variable" is result of the compile time tracing.

Const_cast is exactly the same. By result of compiling of block of code
compiler generates public name for function as
- "foo$const_int&%readonly$" - if const_cast was never used
- "foo$const_int&%writable$' - if const_cast was used

void test()
{
std::vector<const int*> intlist;

fill_list(intlist);

"fill_list" undeclared here
for (size_t i = 0; i < intlist.size(); i++)
foo(intlist);


assuming "foo(*intlist)" due to "foo" declaration

void foo ( const int &); // foo$const_int&$

Here compiler request external foo(const int&), concrete const overloading
"%writable" or "%readonly" depended from "std::vector::eek:perator[]"
declaration only.

If "std::vector::eek:perator[]" return "const_int&%writable" (const reference
to writeable memory) compiler will generate request to external as for
writable segment

If "std::vector::eek:perator[]" return "const_int&%readonly" (const reference
to readonly memory) compiler will generate request to external as for
readonly segment
}

Why should they do that anyway? Why have /const/ and /the_true_const/ if
you can have the same with const and non-const?

I have written about some messages ago - to support possible hadrware
memory managers - they can disable writing to readonly memory and support
many other tests "on fly", without any overhead.
 
G

Grizlyk

Gavin said:
I've read several of your posts recently and I think it might help
others to understand your point of view if you could distinguish
between two different situations:
1. Occasions when you are describing how you believe C++ works.

It is true and not true.

In some place I can not prove my opinion by concrete parts of standard and
write "i think". In other places i am sure that without any "believe C++
works" C++ doing concrete things and I do not write "i think".

2. Occasions when you are describing how you feel some hypothetical
future version of C++ ought to work.

It is because of I see C++ as C++ user, not as "C++ standard cometee", so I
look to C++ from problem side (i am just trying to solve detected
difficulty) and do not try to trim myself by strange and unexplainable
standard limitations. My goal is not to prove that standard also can be
used.

This way do not contradicts to attemts to push all to pure standard, because
i do not say, that any must use properties, that can not be compiled and do
not say that the non-standard properties is standard properties.

I have responded to posts of yours in the past by attempting to
correct an apparent misunderstanding of C++ on your part, only to
discover later in the discussion that you appear to be talking not
about C++, but about some hypothetical future version of the language.

At least when people became speak about theoretical abilities of C++ (that
compiler can not do something in theory) I do not see any obstacles to speak
about "what if".
 
G

Grizlyk

JLS said:
This is my argument for using const. Some number of bugs will be
caught using const. It makes the code clearer and more understandable.
There is no down side, so why not use it?

Exactly. There are tons of bugs, sucsessully detected by const. Most system
even have hardware const support, because try to do const violation is just
error. Const makes parts of programs more isolated so it is easyer to
maintain. Anyway no one man wants to write into M_PI due to save memory.

For C++ const has a special meaning, const variables can be conpile time
constants if its adress never taken.
 
G

Gavin Deane

It is because of I see C++ as C++ user, not as "C++ standard cometee", so I
look to C++ from problem side (i am just trying to solve detected
difficulty) and do not try to trim myself by strange and unexplainable
standard limitations. My goal is not to prove that standard also can be
used.

The topic of this newsgroup is C++, as defined by the standard, with
all its limitations - strange and unexplainable or otherwise. That's
what people here know about and expect to be discussing.
At least when people became speak about theoretical abilities of C++ (that
compiler can not do something in theory) I do not see any obstacles to speak
about "what if".

If that "what if" takes you outside the C++ standard, even if that
seems strange and unexplainable, consider two things:
1. Unless you make it clear that you know you are outside the
standard, you will attract responses telling you that you are, simply
because the scope of this group is the scope of the C++ standard.
2. Your discussion may be more topical in another forum (e.g comp.std.c
++) which means that you will be discussing with people who expect you
to be talking about things outside the scope of the standard - the
opposite of what people here expect.

Gavin Deane
 
G

Grizlyk

Gavin said:
If that "what if" takes you outside the C++ standard, even if that
seems strange and unexplainable, consider two things:
1. Unless you make it clear that you know you are outside the
standard, you will attract responses telling you that you are, simply
because the scope of this group is the scope of the C++ standard.
2. Your discussion may be more topical in another forum (e.g comp.std.c
++) which means that you will be discussing with people who expect you
to be talking about things outside the scope of the standard - the
opposite of what people here expect.

Maybe you are right and sometimes people just whant to use the group as
"fast dictionary" of standard, asking what standard required for concrete
accident. It is useful application.

But where anyone can ask ordinary C++ users about possible standard
extentions? And it seems that it is hard to understand some parts of
standards without consideration bounds of standard.
 
G

Gavin Deane

Maybe you are right and sometimes people just whant to use the group as
"fast dictionary" of standard, asking what standard required for concrete
accident. It is useful application.

That's a fair summary of the purpose of this newsgroup, as described
in FAQ 5.9
http://www.parashift.com/c++-faq-lite/how-to-post.html#faq-5.9
But where anyone can ask ordinary C++ users about possible standard
extentions? And it seems that it is hard to understand some parts of
standards without consideration bounds of standard.

The first two FAQs for comp.std.c++ should give you an idea whether
your question is more likely to be topical (and therefore attract more
productive discussion) there.
http://www.comeaucomputing.com/csc/faq.html

HTH
Gavin Deane
 

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

No members online now.

Forum statistics

Threads
473,785
Messages
2,569,624
Members
45,319
Latest member
LorenFlann

Latest Threads

Top