question about new and delete operator

Discussion in 'C++' started by LiDongning, Jul 3, 2009.

  1. LiDongning

    LiDongning Guest

    Hi,
    I'm working on a class which allocate some memory to store an array
    (pointed by a pointer p_data). In constructor I use new to do the
    allocation, in destructer I use delete to free the memory. In one
    member function I wan to do something with the data (say, sort). In
    that case, inside that function, I plan to allocate a piece memory to
    store the processed data (p_processed), then free the original memory
    (p_data), and point the p_data to p_process. The code will be
    something like attached below. My question is, can i do something like
    in the last two lines of code? Will this cause a memory leak or any
    harmful effect? Thanks very much!

    template <class T>
    class data
    {
    int datanum;
    T* p_data;
    public:
    data(int, T*);
    ~data();
    void process();
    };

    template <class T>
    data<T>::data(int in_n, T* in_data):datanum(in_n)
    {
    T* p_data = new T[datanum];
    for (int i=0; i<datanum; i++) {p_data=in_data;}
    }

    template <class T>
    data<T>::~data()
    {
    delete []p_data;
    }

    template <class T>
    void data<T>::process()
    {
    T* p_processed= new T[datanum];
    //do something, so p_processed will be filled with processed data
    for (int i=1; i<datanum; i++) {p_processed=p_data;}
    //processing finished
    delete []p_data; // can i
    do this??
    p_data = p_processed; // can i do
    this??
    }
     
    LiDongning, Jul 3, 2009
    #1
    1. Advertising

  2. LiDongning

    Jonathan Lee Guest

    HI LiDongning,

    > void data<T>::process()
    > {
    >      T* p_processed= new T[datanum];
    >      //do something, so p_processed will be filled with processed data
    >      for (int i=1; i<datanum; i++) {p_processed=p_data;}
    >      //processing finished
    >      delete []p_data;                                        // can i
    > do this??
    >      p_data = p_processed;                             // can i do
    > this??
    >
    > }
    >


    That's fine. You've just exchanged the arrays. p_data will still
    be a valid pointer for when the destructor is called.

    But the way you've phrased it, why not just calculate the result
    directly in p_data and then delete[] p_processed? It seems that they
    are the same size and p_processed is initialized to be a copy
    of p_data. I'm not sure what would stop you from making p_data
    the destination for your processing. If you were really cautious
    about the delete[], then that would be a solution.

    --Jonathan
     
    Jonathan Lee, Jul 3, 2009
    #2
    1. Advertising

  3. LiDongning

    Yan Guest

    On Jul 3, 3:57 pm, LiDongning <> wrote:

    >      T* p_processed= new T[datanum];
    >      //do something, so p_processed will be filled with processed data
    >      for (int i=1; i<datanum; i++) {p_processed=p_data;}
    >      //processing finished
    >


    it's seems all good. i would however, if i were you, make sure that
    the 'processing' part doesn't throw, because if it does the memory
    allocated for p_processed won't get freed.
     
    Yan, Jul 3, 2009
    #3
  4. LiDongning schrieb:
    > Hi,
    > I'm working on a class which allocate some memory to store an array
    > (pointed by a pointer p_data). In constructor I use new to do the
    > allocation, in destructer I use delete to free the memory. In one
    > member function I wan to do something with the data (say, sort). In
    > that case, inside that function, I plan to allocate a piece memory to
    > store the processed data (p_processed), then free the original memory
    > (p_data), and point the p_data to p_process. The code will be
    > something like attached below. My question is, can i do something like
    > in the last two lines of code? Will this cause a memory leak or any
    > harmful effect? Thanks very much!
    >


    I would recommend to use std::vector like this:

    #include <vector>

    template <class T>
    class data
    {
    std::vector<T> m_data;
    public:
    data(int, T*);
    void process();
    };

    template <class T>
    data<T>::data(int in_n, T* in_data)
    : m_data( in_data, in_data + in_n )
    {
    }

    template <class T>
    void data<T>::process()
    {
    std::vector<T> processed( m_data.begin(), m_data.end() );
    // do something with your copy

    // assign processed data to m_data
    m_data.swap( processed );
    }


    This code is shorter *and* exception safe.


    Lars
     
    Lars Tetzlaff, Jul 4, 2009
    #4
  5. LiDongning

    LiDongning Guest

    On Jul 3, 3:17 pm, Jonathan Lee <> wrote:
    > HI LiDongning,
    >
    > > void data<T>::process()
    > > {
    > >      T* p_processed= new T[datanum];
    > >      //do something, so p_processed will be filled with processed data
    > >      for (int i=1; i<datanum; i++) {p_processed=p_data;}
    > >      //processing finished
    > >      delete []p_data;                                        // can i
    > > do this??
    > >      p_data = p_processed;                             // can i do
    > > this??

    >
    > > }

    >
    > That's fine. You've just exchanged the arrays. p_data will still
    > be a valid pointer for when the destructor is called.
    >
    > But the way you've phrased it, why not just calculate the result
    > directly in p_data and then delete[] p_processed? It seems that they
    > are the same size and p_processed is initialized to be a copy
    > of p_data. I'm not sure what would stop you from making p_data
    > the destination for your processing. If you were really cautious
    > about the delete[], then that would be a solution.
    >
    > --Jonathan


    Jonathan,
    Thanks for the reply. The reason I allocate a p_process array is that
    I want to do a sorting for the data in the p_data array. If I use a
    binary tree algorithm, the original data have to be kept until the
    sorting is finished.
    DOngning
     
    LiDongning, Jul 4, 2009
    #5
  6. LiDongning

    LiDongning Guest

    On Jul 4, 6:27 am, Lars Tetzlaff <> wrote:
    > LiDongning schrieb:
    >
    > > Hi,
    > > I'm working on a class which allocate some memory to store an array
    > > (pointed by a pointer p_data). In constructor I use new to do the
    > > allocation, in destructer I use delete to free the memory. In one
    > > member function I wan to do something with the data (say, sort). In
    > > that case, inside that function, I plan to allocate a piece memory to
    > > store the processed data (p_processed), then free the original memory
    > > (p_data), and point the p_data to p_process. The code will be
    > > something like attached below. My question is, can i do something like
    > > in the last two lines of code? Will this cause a memory leak or any
    > > harmful effect? Thanks very much!

    >
    > I would recommend to use std::vector like this:
    >
    > #include <vector>
    >
    > template <class T>
    > class data
    > {
    >   std::vector<T> m_data;
    > public:
    >   data(int, T*);
    >   void process();
    >
    > };
    >
    > template <class T>
    > data<T>::data(int in_n, T* in_data)
    > : m_data( in_data, in_data + in_n )
    > {
    >
    > }
    >

    Exactly! Thanks much!

    > template <class T>
    > void data<T>::process()
    > {
    >   std::vector<T> processed( m_data.begin(), m_data.end() );
    >   // do something with your copy
    >
    >   // assign processed data to m_data
    >   m_data.swap( processed );
    >
    > }
    >
    > This code is shorter *and* exception safe.
    >
    > Lars
     
    LiDongning, Jul 4, 2009
    #6
  7. Hendrik Schober wrote:
    > Why 'int'? Will there ever be a sequence of -5 bytes?


    In my experience using signed types even in situations where negative
    values have no rational meaning lessens problems in the long run.

    For example, assume you are making a class which represents an image.
    The class will have two integral members denoting the pixel width and
    height of the image. Since it doesn't make sense to have images with
    negative width or height, the most logical thing to do would be to make
    these two integrals unsigned, right?

    Well, no. Let's assume that in the application where the class is used
    the images are drawn on screen, eg. as sprites. The image may be drawn
    partially outside of the screen. In other words, the coordinates where
    the image is drawn may well be negative.

    Now, if you need to perform any arithmetic using the coordinates and
    the dimensions of the image (which is very usual in such situations),
    you will have a clash between signed and unsigned types. In certain
    situations you might end up with incorrect results (eg. if floating
    point calculations are involved, something might end up at the
    coordinate 4294967295 or whatever). I have had this problem in practice,
    so it's not purely theoretical stuff.
     
    Juha Nieminen, Jul 5, 2009
    #7
  8. LiDongning

    James Kanze Guest

    On Jul 5, 10:39 pm, Hendrik Schober <> wrote:
    > Lars Tetzlaff wrote:
    > > LiDongning schrieb:


    > >> I'm working on a class which allocate some memory to store
    > >> an array (pointed by a pointer p_data). In constructor I
    > >> use new to do the allocation, in destructer I use delete to
    > >> free the memory. In one member function I wan to do
    > >> something with the data (say, sort). In that case, inside
    > >> that function, I plan to allocate a piece memory to store
    > >> the processed data (p_processed), then free the original
    > >> memory (p_data), and point the p_data to p_process. The
    > >> code will be something like attached below. My question is,
    > >> can i do something like in the last two lines of code? Will
    > >> this cause a memory leak or any harmful effect? Thanks very
    > >> much!


    > > I would recommend to use std::vector like this:


    > > #include <vector>


    > > template <class T>
    > > class data
    > > {
    > > std::vector<T> m_data;
    > > public:
    > > data(int, T*);
    > > void process();
    > > };


    > > template <class T>
    > > data<T>::data(int in_n, T* in_data)
    > > : m_data( in_data, in_data + in_n )
    > > {
    > > }


    > Why 'int'? Will there ever be a sequence of -5 bytes?


    Because int is the "standard" type for integral values in C++.
    Anything else should only be used if int won't do the job; the
    only justification for not using int here would be that there
    might be sequences of more that INT_MAX bytes.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Jul 6, 2009
    #8
  9. * Hendrik Schober:
    > Paavo Helde wrote:
    >> Hendrik Schober <> kirjutas:
    >> [...]
    >>> Why 'int'? Will there ever be a sequence of -5 bytes?

    >>
    >> We have had this discussion before in this group, several times.

    >
    > I'm sorry I missed this. I'm not a regular reader. I don't
    > have enough time to be. Feel free to ignore any discussion
    > stemming from this.
    >
    >> In
    >> C++, the unsigned types are quite specific types with special rollover
    >> effects and there are tricky promotion rules for mixed-signedness
    >> arithmetic expressions. Unless unsignedness is strongly needed, I
    >> would avoid those types.

    >
    > Well, call me strict, but I happen to believe that, for
    > specifying sizes, unsignedness is strongly needed. I also
    > believe that, if a positive value is needed in order to
    > call a function, the function's interface should say so.
    > Yes, I know, implicit promotion etc. can wreak havoc when
    > you have huge unsigned numbers.


    Apparently you don't understand the problems.


    > Still, if I have to decide
    > between having the right interface and maybe having to
    > find funny errors due to this, or having a wrong interface
    > and maybe having to find funny errors due to negative
    > values being past, I'd go for the right interface.


    In C or C++, unsigned type is far more likely to yield "funny errors".

    Choosing types in a good way is a matter of programming language.



    Cheers & hth.,

    - Alf
     
    Alf P. Steinbach, Jul 7, 2009
    #9
  10. LiDongning

    James Kanze Guest

    On Jul 7, 11:08 am, Hendrik Schober <> wrote:
    > James Kanze wrote:
    > > On Jul 5, 10:39 pm, Hendrik Schober <> wrote:
    > >> Lars Tetzlaff wrote:

    > > [...]
    > >>> template <class T>
    > >>> data<T>::data(int in_n, T* in_data)
    > >>> : m_data( in_data, in_data + in_n )
    > >>> {
    > >>> }


    > >> Why 'int'? Will there ever be a sequence of -5 bytes?


    > > Because int is the "standard" type for integral values in
    > > C++. Anything else should only be used if int won't do the
    > > job; the only justification for not using int here would be
    > > that there might be sequences of more that INT_MAX bytes.


    > You state this as an axiom.


    Because it is an axiom. It's part of the original definition of
    C.

    > Note that I asked "why".


    Because that's the way the language designers designed the
    language. I'm not saying that it's right---I sort of liked
    Modula-2's CARDINAL type. But C and C++ don't have one.

    > Had I subscribed to the axiom, I wouldn't have asked.
    > (To cut a few corners in this discussion: I subscribe
    > to the axiom of always choosing the data type that is
    > the best representation of the data. If the data is
    > natural, positive numbers, an unsigned type seems to
    > be the natural fit for the job.)


    To be reasonable, you need to include behavior in the
    representation. If the data is natural, positive numbers,
    subtraction can still result in a negative value---when choosing
    a type, either the type will allow a signed result in the case
    of subtraction, or it won't support subtraction (case of
    Modula-2). You also have to choose the type in the context of
    the whole type system: in C++, if you use unsigned in an
    expression with a signed, it changes the meaning of the signed
    in strange ways.

    In the end, a language is designed the way it is designed. You
    can fight it, but you won't win. Kernighan and Richie decided
    that the principal integral type in C would be int; all other
    types have been added for specific needs, but int remains THE
    integral type. Anytime you use anything else (for integral
    values, of course), you're fighting the language: introducing
    additional complexity and additional possibilities for errors.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Jul 7, 2009
    #10
  11. LiDongning

    Bo Persson Guest

    Hendrik Schober wrote:
    > Paavo Helde wrote:
    >> Hendrik Schober <> kirjutas:
    >> [...]
    >>> Why 'int'? Will there ever be a sequence of -5 bytes?

    >>
    >> We have had this discussion before in this group, several times.

    >
    > I'm sorry I missed this. I'm not a regular reader. I don't
    > have enough time to be. Feel free to ignore any discussion
    > stemming from this.
    >
    >> In
    >> C++, the unsigned types are quite specific types with special
    >> rollover effects and there are tricky promotion rules for
    >> mixed-signedness arithmetic expressions. Unless unsignedness is
    >> strongly needed, I would avoid those types.

    >
    > Well, call me strict, but I happen to believe that, for
    > specifying sizes, unsignedness is strongly needed. I also
    > believe that, if a positive value is needed in order to
    > call a function, the function's interface should say so.


    But that doesn't save you from anyone passing a -5, as that will
    "work" for an unsigned parameter as well.



    Bo Persson
     
    Bo Persson, Jul 7, 2009
    #11
  12. * Hendrik Schober:
    > Bo Persson wrote:
    >> Hendrik Schober wrote:
    >>> Paavo Helde wrote:
    >>>> Hendrik Schober <> kirjutas:
    >>>> [...]
    >>>>> Why 'int'? Will there ever be a sequence of -5 bytes?
    >>>> We have had this discussion before in this group, several times.
    >>> I'm sorry I missed this. I'm not a regular reader. I don't
    >>> have enough time to be. Feel free to ignore any discussion
    >>> stemming from this.
    >>>
    >>>> In
    >>>> C++, the unsigned types are quite specific types with special
    >>>> rollover effects and there are tricky promotion rules for
    >>>> mixed-signedness arithmetic expressions. Unless unsignedness is
    >>>> strongly needed, I would avoid those types.
    >>> Well, call me strict, but I happen to believe that, for
    >>> specifying sizes, unsignedness is strongly needed. I also
    >>> believe that, if a positive value is needed in order to
    >>> call a function, the function's interface should say so.

    >>
    >> But that doesn't save you from anyone passing a -5, as that will
    >> "work" for an unsigned parameter as well.

    >
    > Of course, it doesn't. However, it does communicate
    > that -5 is not a valid value.


    If you fail to communicate the function's contract to client programmers then
    you have a problem. You seem to think that that communication problem can be
    alleviated by using unsigned types in C or C++. Well that's backward: to anyone
    competent you're just communicating that you don't know what you're about, so
    that it would be wrong to expect *anything* to be reasonable, i.e., by using
    unsigned type you actively engage in failing to do what you wanted, communicate.

    And if the function fails to enforce its contract to the degree possible you
    have a much more serious problem, because all experience shows that without
    automated error detection it's practically impossible to avoid errors.

    The client code programmer may have a 100% perfect understanding of your
    function's contract, but still manage to call it with invalid arguments.

    And what happens when you pass -5 to your unsigned formal argument?

    The language standard then guarantees wrapping, that you get the value 2^n-5
    where n is the number of value representation bits, and do you check for that?
    No? I thought so.


    Cheers & hth.,

    - Alf
     
    Alf P. Steinbach, Jul 8, 2009
    #12
  13. LiDongning

    James Kanze Guest

    On Jul 7, 7:13 pm, Hendrik Schober <> wrote:
    > Bo Persson wrote:


    [...]
    > > But that doesn't save you from anyone passing a -5, as that will
    > > "work" for an unsigned parameter as well.


    > Of course, it doesn't. However, it does communicate that -5 is
    > not a valid value.


    Not really, since -5 is a perfectly legal value to use when
    initializing an unsigned. But that's not really the point: the
    unsigned integral types in C++ are fairly special, and using
    unsigned communicates (to someone who knows C++, at least) that
    you require some of its special qualities: modulo arithmetic, or
    correct behavior for bitwise operators.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Jul 8, 2009
    #13
  14. LiDongning

    James Kanze Guest

    On Jul 7, 4:05 pm, Hendrik Schober <> wrote:
    > James Kanze wrote:
    > > On Jul 7, 11:08 am, Hendrik Schober <> wrote:
    > >> James Kanze wrote:
    > >>> On Jul 5, 10:39 pm, Hendrik Schober <> wrote:
    > >>>> Lars Tetzlaff wrote:
    > >>> [...]
    > >>>>> template <class T>
    > >>>>> data<T>::data(int in_n, T* in_data)
    > >>>>> : m_data( in_data, in_data + in_n )
    > >>>>> {
    > >>>>> }


    > >>>> Why 'int'? Will there ever be a sequence of -5 bytes?


    > >>> Because int is the "standard" type for integral values in
    > >>> C++. Anything else should only be used if int won't do
    > >>> the job; the only justification for not using int here
    > >>> would be that there might be sequences of more that
    > >>> INT_MAX bytes.


    > >> You state this as an axiom.


    > > Because it is an axiom. It's part of the original
    > > definition of C.


    > Mhmm. I've never owned a C standard, so I only know from
    > hearsay, but so far I always assumed 'int' was "the native
    > integer type on the platform",


    And how is this different from "the standard type"?

    > meaning that it is the one the platform is fastest with.


    Speed doesn't necessarily have much to do with it. It's true
    that on some platforms, anything involving unsigned is
    significantly slower than signed, but on most platforms, it
    makes absolutely no difference, and never had.

    > > [...]
    > > To be reasonable, you need to include behavior in the
    > > representation. If the data is natural, positive numbers,
    > > subtraction can still result in a negative value [...]


    > Yep. And when dividing with 'double', you have to be
    > careful, since a '0.0' might be fatal. What's the
    > fundamental different to subtracting unsigned integers?


    Because there's no relationship whatsoever between them. The
    subtraction of two natural numbers is a well defined operation;
    division by 0 isn't.

    > > In the end, a language is designed the way it is designed. You
    > > can fight it, but you won't win. Kernighan and Richie decided
    > > that the principal integral type in C would be int; all other
    > > types have been added for specific needs, but int remains THE
    > > integral type. Anytime you use anything else (for integral
    > > values, of course), you're fighting the language: introducing
    > > additional complexity and additional possibilities for errors.


    > Mhmm. Then who added 'size_t' to be used for sizes
    > to this language?


    I don't know. That came a lot later. (Don't forget, however,
    that size_t was originally designed to represent something very
    low level, which often wouldn't fit in an int.)

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Jul 8, 2009
    #14
  15. On 8 July, 10:37, Hendrik Schober <> wrote:
    > Alf P. Steinbach wrote:
    > > * Hendrik Schober:
    > >> Bo Persson wrote:
    > >>> Hendrik Schober wrote:
    > >>>> Paavo Helde wrote:


    <snip>

    > >>>>> In
    > >>>>> C++, the unsigned types are quite specific types with special
    > >>>>> rollover effects and there are tricky promotion rules for
    > >>>>> mixed-signedness arithmetic expressions. Unless unsignedness is
    > >>>>> strongly needed, I would avoid those types.

    >
    > >>>> Well, call me strict, but I happen to believe that, for
    > >>>> specifying sizes, unsignedness is strongly needed.


    why?

    > >>>> I also
    > >>>> believe that, if a positive value is needed in order to
    > >>>> call a function, the function's interface should say so.


    ok. DbC and all that

    > >>> But that doesn't save you from anyone passing a -5, as that will
    > >>> "work" for an unsigned parameter as well.

    >
    > >> Of course, it doesn't. However, it does communicate
    > >> that -5 is not a valid value.


    not really as you can stuff -5 into an C++ unsigned type.
    The point being that C++ unsigned types have odd (though useful)
    semantics


    > > If you fail to communicate the function's contract to client programmers then
    > > you have a problem.  


    yes

    > Right. Which is why I put great emphasis on communicating
    > this. In the language, rather than in comments.


    Alf never said comments. In fact he talks about "automatic
    detection". I think he's thinking asserts or similar measures.


    > > You seem to think that that communication problem can be
    > > alleviated by using unsigned types in C or C++. [...]

    >
    > And you seem to think that communication between callers
    > and callees has to happen solely through comments. (Just
    > as stupid an accusation, I know. Couldn't resist, though.)


    since he never said that, that makes most of the next paragraph
    moot


    > If communication solely through comments was fine, all
    > functions should take and return only 'void*'. (Or they
    > might take an ellipsis. You can communicate the number
    > of arguments through comments, after all.) Since this not
    > only isn't done, but frowned upon, and since the language
    > even more and more develops towards the exact opposite
    > (expressing of constraints directly in the language,
    > instead of in comments), I conclude there's a general
    > consensus that this is better.


    I fwe thought this was generally true we'd be writing Ada

    > > The client code programmer may have a 100% perfect understanding of your
    > > function's contract, but still manage to call it with invalid arguments..

    >
    > > And what happens when you pass -5 to your unsigned formal argument?

    >
    > > The language standard then guarantees wrapping, that you get the value 2^n-5
    > > where n is the number of value representation bits, and do you check for that?
    > > No? I thought so.

    >
    > Does your implementation of
    >    std::vector<T>::eek:perator[](size_type)
    > check whether you pass -5 into it?


    I believe there are checking versions. The STL generally
    emphasises speed. It's up to you to validate arguments before you
    pass
    them to the STL. You wouldn't read the index from a terminal and then
    pass it to the STL would you?


    > No? I thought so.
    > And what happens if you do anyway? Right. I thought so,
    > too.
    > And if you manage to still get this wrong even though
    > you have a 100% perfect understanding of the fact that
    > the operator requires an unsigned? See. Again, I thought
    > so.



    --
    Nick Keighley
     
    Nick Keighley, Jul 9, 2009
    #15
  16. On 7 July, 12:43, James Kanze <> wrote:
    > On Jul 7, 11:08 am, Hendrik Schober <> wrote:
    > > James Kanze wrote:
    > > > On Jul 5, 10:39 pm, Hendrik Schober <> wrote:
    > > >> Lars Tetzlaff wrote:


    > > >>> template <class T>
    > > >>> data<T>::data(int in_n, T* in_data)
    > > >>> : m_data( in_data, in_data + in_n )
    > > >>> {
    > > >>> }

    >
    > > >> Why 'int'? Will there ever be a sequence of -5 bytes?

    >
    > > > Because int is the "standard" type for integral values in
    > > > C++.  Anything else should only be used if int won't do the
    > > > job; the only justification for not using int here would be
    > > > that there might be sequences of more that INT_MAX bytes.

    >
    > > You state this as an axiom.

    >
    > Because it is an axiom.  It's part of the original definition of
    > C.


    I don't recall this (and *I* have read the ANSI C standard). You
    seemed to be stating a *design* axiom. That you use int unless there
    is a reason to the contrary. I don't see this being part of the
    original
    language definition. It may be sensible but I don't see it as being
    axiomatic.


    <snip>


    --
    Nick keighley
     
    Nick Keighley, Jul 9, 2009
    #16
  17. LiDongning

    James Kanze Guest

    On Jul 9, 10:24 am, Nick Keighley <>
    wrote:
    > On 7 July, 12:43, James Kanze <> wrote:
    > > On Jul 7, 11:08 am, Hendrik Schober <> wrote:
    > > > James Kanze wrote:
    > > > > On Jul 5, 10:39 pm, Hendrik Schober <> wrote:
    > > > >> Lars Tetzlaff wrote:
    > > > >>> template <class T>
    > > > >>> data<T>::data(int in_n, T* in_data)
    > > > >>> : m_data( in_data, in_data + in_n )
    > > > >>> {
    > > > >>> }


    > > > >> Why 'int'? Will there ever be a sequence of -5 bytes?


    > > > > Because int is the "standard" type for integral values in
    > > > > C++. Anything else should only be used if int won't do the
    > > > > job; the only justification for not using int here would be
    > > > > that there might be sequences of more that INT_MAX bytes.


    > > > You state this as an axiom.


    > > Because it is an axiom. It's part of the original
    > > definition of C.


    > I don't recall this (and *I* have read the ANSI C standard).


    The ISO C standard isn't the original definition of C.
    Kernighan and Richie are (but I think you've read them as well).
    The original C didn't even have unsigned. (It was added, along
    with long, before the K&R book was published, however. I don't
    have my copy of the book handy to verify, but I do seem to
    remember something about "int being the natural type" in there.)

    > You seemed to be stating a *design* axiom. That you use int
    > unless there is a reason to the contrary. I don't see this
    > being part of the original language definition. It may be
    > sensible but I don't see it as being axiomatic.


    Well, the committee did redefine it (at least compared to the
    compilers I was using at the time, including Johnson's pcc) in a
    way that means that you can't effectively mix it with signed
    integers, so that things like "someUnsigned < -5" may be true.
    Which certainly implies that they didn't mean for it to be used
    for numeric values.

    I'm not sure what Kernighan and Richie intended when they first
    introduced it. But at least the compilers I used which came
    from AT&T at the time did interpret "someUnsigned < -5" as
    always false. (At least as I remember it. It's been quite some
    time since I've used pcc.)

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Jul 9, 2009
    #17
  18. LiDongning

    Greg Herlihy Guest

    On Aug 4, 11:29 am, Hendrik Schober <> wrote:
    > James Kanze wrote:
    > >> Yep. And when dividing with 'double', you have to be
    > >> careful, since a '0.0' might be fatal. What's the
    > >> fundamental different to subtracting unsigned integers?

    >
    > > Because there's no relationship whatsoever between them.  The
    > > subtraction of two natural numbers is a well defined operation;

    >
    > ...that has a result which cannot be represented by
    > a natural number. <shrug>


    In C++, the difference between any two unsigned numbers is always
    another unsigned number. So the reason why an unsigned type is such a
    poor choice to represent a natural number - is because an unsigned
    type does not behave like a natural number. And since representing
    data is as much about representing behavior as it is about
    representing a value - it should be clear that - when representing
    numeric values - an unsigned type should always be the choice of last
    resort.

    Greg
     
    Greg Herlihy, Aug 5, 2009
    #18
  19. LiDongning

    James Kanze Guest

    On Aug 4, 8:18 pm, Hendrik Schober <> wrote:
    > Nick Keighley wrote:
    > > On 8 July, 10:37, Hendrik Schober <> wrote:
    > > [old debate generously snipped]


    > >> Does your implementation of
    > >> std::vector<T>::eek:perator[](size_type)
    > >> check whether you pass -5 into it?


    > > I believe there are checking versions. [...]


    > I wonder how they check this.


    They don't have to. It's impossible. size_type must be
    unsigned, so there's no possible way to pass a -5 through it.

    Of course, the results of converting -5 to size_type are going
    to be a very larger number. Almost (but not quite) surely large
    enough, in most cases, that it will be out of bounds.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Aug 5, 2009
    #19
  20. LiDongning

    James Kanze Guest

    On Aug 4, 8:29 pm, Hendrik Schober <> wrote:

    [...]
    > > Because there's no relationship whatsoever between them. The
    > > subtraction of two natural numbers is a well defined operation;


    > ...that has a result which cannot be represented by
    > a natural number. <shrug>


    Exactly. And if the language defines a type T such that T - T
    -> T, then that type isn't an abstraction of the natural
    numbers. For a type to be usable as an abstraction of the
    natural numbers, the results of subtraction must be another
    type, or subtraction must not be supported. (Modula-2, for
    example, takes that latter course.) C++ doesn't have such a
    type; the closest we can come is int.

    > > [...]
    > >>> In the end, a language is designed the way it is designed. You
    > >>> can fight it, but you won't win. Kernighan and Richie decided
    > >>> that the principal integral type in C would be int; all other
    > >>> types have been added for specific needs, but int remains THE
    > >>> integral type. Anytime you use anything else (for integral
    > >>> values, of course), you're fighting the language: introducing
    > >>> additional complexity and additional possibilities for errors.


    > >> Mhmm. Then who added 'size_t' to be used for sizes
    > >> to this language?


    > > I don't know. That came a lot later. (Don't forget, however,
    > > that size_t was originally designed to represent something very
    > > low level, which often wouldn't fit in an int.)


    > It is recycled throughout most of the C++ std lib (as
    > 'size_type').


    I know. That's obviously an error in the conception of the
    library, but it's too late to change it now, despite the
    problems it causes.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Aug 5, 2009
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. HeroOfSpielburg
    Replies:
    1
    Views:
    397
    Alf P. Steinbach
    Aug 6, 2003
  2. Jason
    Replies:
    11
    Views:
    543
    Jonathan Turkanis
    Feb 12, 2004
  3. Jef Driesen
    Replies:
    1
    Views:
    509
    Gernot Frisch
    Jan 19, 2005
  4. xmllmx
    Replies:
    6
    Views:
    421
    xmllmx
    Feb 3, 2010
  5. X X
    Replies:
    4
    Views:
    358
    red floyd
    Jul 19, 2010
Loading...

Share This Page