peter said:
As i know, for each program we get at least one (hard to
detect and with random runtime apperance) error due
to improper delete/delete[] usage.
Not in idiomatic C++ where you "never" use operator delete [].
I see the Old lovely topic - a special meaning of std library in the
world
.
I suspect, you are speaking about ideal situation, where we do not use
C-style arrays or C-style arrays allocated in heap, because we are
replacing them with the help of appropreate wrappers, don't?
I think, we even can go further, and can refuse from explicit raw
memory management with new and delete, and replace all of them with
appropreate wrappers and its messages: wrapper(...), ~wrapper,
wrapper_new(...) etc.
Let's move discussion about the ideas to some lines below.
It is quite stupid from a C++ viewpoint as it looks
more like C. In this case, You should expect using C,
not C++ style.
"stupid from a C++ viewpoint"
Program can not be stupid due to viewpoint of concrete style or
paradigm. Stupid is just because simple, the program does nothing,
copying some lines from several files into one file.
"looks more like C"?
How will you express the following code from the program with the help
of C and why:
code example
// ***********************
template <class Tobj, class Tc_heap=Theap_array<Tobj> >
class Tarray_holder:
public Nholder::Tarray_holder_intf<Tobj,Tc_heap>
{
typedef Nholder::Tarray_holder_intf<Tobj,Tc_heap> Tparent;
using Tparent::memory;
public:
//from new Tobj[]
Tarray_holder&
set_array (Tobj *const obj)
{ Tparent::set_array(obj); return *this; }
Tarray_holder&
operator= (Tobj *const obj)
{ return set_array(obj); }
Tarray_holder(Tobj *const obj=0):Tparent(obj){}
~Tarray_holder(){ memory.destroy(); }
private:
Tarray_holder(const Tarray_holder&);
void operator= (const Tarray_holder&);
};
// *******************
//lists of reffered lines
list<Tfile> files;
uint files_size=0;
// *********************************************
// *********************************************
int main(int argc, char *argv[])
{
FILE *fo=0;
try{
if(argc!=2)usage();
char *in_fname=argv[1];
Tarray_holder<char> out_fname;
{
out_fname= new char[VALUE];
strcpy( out_fname(0), in_fname );
fo=fopen(out_fname(0),"wt");
if(!fo)throw Terr( out_fname(0) );
}
for(;
{
if(feof(fi))break;
//next line
getln(buf,MAX_LEN,fi);
++asm_lines;
if(!buf[0])continue;
//test file number is dublicated
if(
files_size
&& ( find_file(number) != files.end() )
)
{
f_st[0]='"';
f_end[0]='"';
fprintf(
stderr,
tpl_bad_format,
asm_lines,
file_sign,
"dublicated file number",
buf);
continue;
}
files.push_back(tmp);
++files_size;
}
// ******************
//try
}
catch(const char* err)
{ fprintf(stderr,"error: %s\n",err); }
catch(Terr& err)
{ fprintf(stderr,"error: %s\n",err.what()); }
catch(...)
{ fprintf(stderr,"error: %s\n","unknown"); }
// ******************
//main
}
end of code example
1. possible memory leakage.
char *const tmp=new char[len+1];
strcpy(tmp,who);
msg_copied=tmp;
}
catch(...){ msg_shared="no memory"; }
"strcpy(tmp,who)" can throw while "tmp" has no owner
This is not possible so far as I know.
strcpy is C and thus does not throw.
Did you write your own strcpy?
I trust C-library in most cases, but for some situation wrappers or
even code replacement required for C-style function in C++ scope. In
the case of "strcpy", that will be comiled into "rep movsl", what kind
of replacement could be done without lost of perfomance?
Often std::strcpy can produce one of SIGxxx, so the best solution is
if target C++ executable enviroment will work to convert hardware
exception into C++ exception. The other solution is explicit throwing
exception from not_std::strcpy implementation.
Looking at the code, it is impossible to say what kind of strcpy
implementation are used, because the code is independent from any
strcpy implementation. I think the independence is reason of
appearence of any function and especially a library.
Original code is not safe, if exception will be thrown, and modified
code is safe. Both of them can not hold on if power of CPU will be
switched off or program will be terminated by OS during strcpy
execution.
Well... you can't fight bad programming in any language.
Are you think, that good programmer work only with assembler or even
directly with CPU opcodes? I guess you beleive no
. The goal of any
high-level language to reduce number of details, that must be used by
programmer simultaneously, to regroup the details into separated and
independent structures. The details with delete/delete[] look like
variable without type.
So, the only way to prevent the errors is explicit memory
declarations:
char * ptr; //C-style pointer
auto char * ptr; //can not delete/delete[]
heap char * ptr; //can delete heap/delete
heap[] char * msg_copied; //can delete heap[]/delete[]
other_memory_type char *ptr; //can delete other_memory_type
Maybe it will be added to C++.
Why? We already have std::vector (and std::string). Using either of
these would have avoided your problems.
For example, just because C-arrays are not prohibited. But speaking
seriously, we sometimes need low-level dinamic buffers for simple DTA
and so on, with special behaviour, so we can write wrappers (other
than vector<>) and use raw memory management.
And returning to suspended idea about "idiomatic C++ where you never
use operator delete []".
I agree, this is not a best way to prove anything by linking to any
authority only, but some of the following ideas are quite
undestandable.
Somewhere about 90-99 years Stroustrup wrote that:
1. C++ was designed to do not insist on any concrete way of
programming. If you say, that the way is poor, you must say what
conrete thing is a problem with the way. The fact of existance of
other ways is not enough.
2. C++ was designed to be set of orthogonal, self-independed parts of
solid language, that means, that you can select and use any set of
parts you wish. If you say, that the part of language must be used
here, you must say what conrete thing is a problem without. The fact
of existance of other parts is not enough.
3. Library ( he was speaking about io implementation ) is _not_ a part
of C++ language. And it is right, because there are many libraries in
the world.
For OOP paradigm the fact of existance of any concrete interface is
often not a problem, due to free-standing classes and functions, that
can be used as adaptors (without any overhead).
It is possible, that under pressure of inconming improvements he has
changed his mind, but it is bad only for him
. Just because we begin
to insist on concrete way of programming or on using of concrete parts
of language.
I can understand people, who wants to remove all modifications into
library, in order to save C++ simple and alive, but it is not always
possible.
Maybe it would be better to strictly divide internals of C++,
implemented by std library, and real user-defined classes, implemented
by std library, that has no any relation to language itself, but only
to certain paradigms or ways of programming.
In the case noone will require to use any library or part of library,
including std library.
From the first view, the best solution to control modification - to
make simple (without syntax shugar and multy-ways of implementation of
anything) core language, including all important stuffs to implement
all supported paradigms. The core could be keeped unmodified, and
extentions or dialects of the core could be added/removed by standard
and then adjusted and used by user in free manner, but i agree, there
are many difficulties in the language like this.
4. I agree, that std library improve portability of code, but it is
impossible to write universal library. It is much better to include
stuffs into language to easy work with inteface of any concrete
library.
(If one want to use std library, take a list of library interfaces and
store the structure into own memory. There are examples, that can help
anybody to learn the library.)
The presence of std library make a strange thing - people became to
see C++ over stdlib: array is a vector<> etc. But it is not true,
Tarray_holder<> is array also.
I am shure, that some people do it from best feeling, but it is
impossible to write with C++ without understanding internals of C++:
memory layout, way of transfer of parameters, exception implementation
etc.
C++ is not like basic, you always will catch unexpected errors without
the knowledge or with the wrong or week knowledge.
It is the same as you can not use profesional OOP libraries without
base knowledge about OOP design, in fact, the libraries only help you
do not repeat the work is done.
In order to be independed from internals of C++ some people invent
artificial rules that is even more complex than original, but has no
any undestandable base. Real rules with example from any real
architecture is easy to understand, than artificial rules.
So large message
.
Maksim A. Polyanin
old page about some C++ improvements:
http://grizlyk1.narod.ru/cpp_new