C++: Uninitialised Variable Passed as a Parm

Discussion in 'C++' started by Gene Wirchenko, Dec 17, 2003.

  1. Is the following guaranteed safe?

    void InitInt(int & SomeInt)
    {
    SomeInt=3;
    return;
    }

    int main()
    {
    int MainInt; // not initialised!
    InitInt(MainInt);
    std::cout << MainInt << std::endl;
    return 0;
    }

    The intent of the function is to initialise its parm, so why
    bother initialising it first in main()? Unless, of course, it is not
    safe. Is it safe?

    Sincerely,

    Gene Wirchenko
    Gene Wirchenko, Dec 17, 2003
    #1
    1. Advertising

  2. On Wed, 17 Dec 2003 18:18:33 GMT, Gene Wirchenko
    <> wrote:

    > Is the following guaranteed safe?


    Oops! I forgot to
    #include <iostream>

    > void InitInt(int & SomeInt)
    > {
    > SomeInt=3;
    > return;
    > }
    >
    > int main()
    > {
    > int MainInt; // not initialised!
    > InitInt(MainInt);
    > std::cout << MainInt << std::endl;
    > return 0;
    > }
    >
    > The intent of the function is to initialise its parm, so why
    >bother initialising it first in main()? Unless, of course, it is not
    >safe. Is it safe?


    Sincerely,

    Gene Wirchenko
    Gene Wirchenko, Dec 17, 2003
    #2
    1. Advertising

  3. Gene Wirchenko

    Chris Theis Guest

    "Gene Wirchenko" <> schrieb im
    Newsbeitrag news:...
    > On Wed, 17 Dec 2003 18:18:33 GMT, Gene Wirchenko
    > <> wrote:
    >
    > > Is the following guaranteed safe?

    >
    > Oops! I forgot to
    > #include <iostream>
    >
    > > void InitInt(int & SomeInt)
    > > {
    > > SomeInt=3;
    > > return;
    > > }
    > >
    > > int main()
    > > {
    > > int MainInt; // not initialised!
    > > InitInt(MainInt);
    > > std::cout << MainInt << std::endl;
    > > return 0;
    > > }
    > >
    > > The intent of the function is to initialise its parm, so why
    > >bother initialising it first in main()? Unless, of course, it is not
    > >safe. Is it safe?


    In principle it´s safe though the practice itself is arguable - why not
    initialize at the point of declaration?
    To see whether it makes sense you´d need to provide some more details of
    your intention.

    Chris
    Chris Theis, Dec 17, 2003
    #3
  4. "Gene Wirchenko" <> a écrit dans le
    message de news: ...
    > On Wed, 17 Dec 2003 18:18:33 GMT, Gene Wirchenko
    > <> wrote:
    >
    > > Is the following guaranteed safe?

    >
    > Oops! I forgot to
    > #include <iostream>
    >
    > > void InitInt(int & SomeInt)
    > > {
    > > SomeInt=3;
    > > return;
    > > }
    > >
    > > int main()
    > > {
    > > int MainInt; // not initialised!
    > > InitInt(MainInt);
    > > std::cout << MainInt << std::endl;
    > > return 0;
    > > }
    > >
    > > The intent of the function is to initialise its parm, so why
    > >bother initialising it first in main()? Unless, of course, it is not
    > >safe. Is it safe?

    >
    > Sincerely,
    >
    > Gene Wirchenko
    >


    sounds perfectly safe to me... nevertheless, I hardly understatnd the point
    of this function : costs a function call and does almost nothing
    interesting... and you don't need the return in the function InitInt.
    Le Géant Vert, Dec 17, 2003
    #4
  5. Gene Wirchenko

    tom_usenet Guest

    On Wed, 17 Dec 2003 18:18:33 GMT, Gene Wirchenko
    <> wrote:

    > Is the following guaranteed safe?
    >
    > void InitInt(int & SomeInt)
    > {
    > SomeInt=3;
    > return;
    > }
    >
    > int main()
    > {
    > int MainInt; // not initialised!
    > InitInt(MainInt);
    > std::cout << MainInt << std::endl;
    > return 0;
    > }
    >
    > The intent of the function is to initialise its parm, so why
    >bother initialising it first in main()? Unless, of course, it is not
    >safe. Is it safe?


    Yes - you don't convert MainInt to an rvalue until after you've given
    it a valid value.

    Tom

    C++ FAQ: http://www.parashift.com/c -faq-lite/
    C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
    tom_usenet, Dec 17, 2003
    #5
  6. "Le Géant Vert" <> wrote...
    >
    > "Gene Wirchenko" <> a écrit dans le
    > message de news: ...
    > > On Wed, 17 Dec 2003 18:18:33 GMT, Gene Wirchenko
    > > <> wrote:
    > >
    > > > Is the following guaranteed safe?

    > >
    > > Oops! I forgot to
    > > #include <iostream>
    > >
    > > > void InitInt(int & SomeInt)
    > > > {
    > > > SomeInt=3;
    > > > return;
    > > > }
    > > >
    > > > int main()
    > > > {
    > > > int MainInt; // not initialised!
    > > > InitInt(MainInt);
    > > > std::cout << MainInt << std::endl;
    > > > return 0;
    > > > }
    > > >
    > > > The intent of the function is to initialise its parm, so why
    > > >bother initialising it first in main()? Unless, of course, it is not
    > > >safe. Is it safe?

    > >
    > > Sincerely,
    > >
    > > Gene Wirchenko
    > >

    >
    > sounds perfectly safe to me... nevertheless, I hardly understatnd the

    point
    > of this function : costs a function call and does almost nothing
    > interesting... and you don't need the return in the function InitInt.


    Gene probably provided the simple function just for illustration purposes.
    The point is that if you pass an uninitialised object by reference, some
    compilers complain (with a warning, of course), often such warning is not
    necessarily founded. That's all.

    Victor
    Victor Bazarov, Dec 17, 2003
    #6
  7. On Wed, 17 Dec 2003 19:39:13 +0100, "Le Géant Vert"
    <> wrote:

    [snip]

    >sounds perfectly safe to me... nevertheless, I hardly understatnd the point
    >of this function : costs a function call and does almost nothing
    >interesting... and you don't need the return in the function InitInt.


    Thank you. As to the nit:

    Oh, come off it! I posted a small program that illustrated my
    point. It is called an example. If the initialisation function had
    included code to initialise a 79 TB structure, it would not have made
    the point any better (and would probably have obscured it).

    Sincerely,

    Gene Wirchenko
    Gene Wirchenko, Dec 17, 2003
    #7
  8. On Wed, 17 Dec 2003 18:46:30 +0000, tom_usenet
    <> wrote:

    >On Wed, 17 Dec 2003 18:18:33 GMT, Gene Wirchenko
    ><> wrote:


    [snip]

    >> The intent of the function is to initialise its parm, so why
    >>bother initialising it first in main()? Unless, of course, it is not
    >>safe. Is it safe?

    >
    >Yes - you don't convert MainInt to an rvalue until after you've given
    >it a valid value.


    Thank you.

    Yes, very deliberately so.

    (I have encountered languages where this would not be safe.)

    Sincerely,

    Gene Wirchenko
    Gene Wirchenko, Dec 17, 2003
    #8
  9. Gene Wirchenko wrote:

    > Is the following guaranteed safe?
    >
    > void InitInt(int & SomeInt) {
    > SomeInt=3;
    > return;
    > }


    This is poor programming practice. The following:

    int InitInt(void) {
    return 3;
    }

    would be much better.

    >
    > int main(int argc, char* argv[]) {
    > int MainInt; // not initialized!
    > InitInt(MainInt);


    int MainInt = InitInt();

    You should *always* try to avoid uninitialized variables.

    > std::cout << MainInt << std::endl;
    > return 0;
    > }
    >
    > The intent of the function is to initialized its parm, so why
    > bother initializing it first in main()? Unless, of course, it is not
    > safe. Is it safe?


    It is *dangerous* because the variable may be used uninitialized.
    If not by you, then by some poor programmer who must maintain your code.
    Good programming habits will help keep you out of trouble.
    E. Robert Tisdale, Dec 17, 2003
    #9
  10. Gene Wirchenko

    jeffc Guest

    "Gene Wirchenko" <> wrote in message
    news:...
    > On Wed, 17 Dec 2003 19:39:13 +0100, "Le Géant Vert"
    > <> wrote:
    >
    > [snip]
    >
    > >sounds perfectly safe to me... nevertheless, I hardly understatnd the

    point
    > >of this function : costs a function call and does almost nothing
    > >interesting... and you don't need the return in the function InitInt.

    >
    > Thank you. As to the nit:
    >
    > Oh, come off it! I posted a small program that illustrated my
    > point. It is called an example.


    Now I think you understand why I object when people post "answers" that are
    off the topic of the original question. Interesting :)
    jeffc, Dec 17, 2003
    #10
  11. jeffc wrote:
    >
    > > Oh, come off it! I posted a small program that illustrated my
    > > point. It is called an example.

    >
    > Now I think you understand why I object when people post "answers" that are
    > off the topic of the original question. Interesting :)


    There is a difference between posting an otherwise valid program which
    just demonstrates an idea and a program which contains a bug unnoticed
    by the poster.

    --
    Karl Heinz Buchegger
    Karl Heinz Buchegger, Dec 17, 2003
    #11
  12. On Wed, 17 Dec 2003 11:24:58 -0800, "E. Robert Tisdale"
    <> wrote:

    >Gene Wirchenko wrote:
    >
    >> Is the following guaranteed safe?
    >>
    >> void InitInt(int & SomeInt) {
    >> SomeInt=3;
    >> return;
    >> }

    >
    >This is poor programming practice. The following:
    >
    > int InitInt(void) {
    > return 3;
    > }
    >
    >would be much better.


    No, because this is only an example of initialisation. For an
    arbitrarily complex initialisation, there might be more than one parm
    being initialised and in such configuration that it could not be
    combined into one structure and thus would not be suitable for a
    return value.

    >> int main(int argc, char* argv[]) {


    I did not write the above line. I wrote:
    int main()

    >> int MainInt; // not initialized!
    >> InitInt(MainInt);

    >
    > int MainInt = InitInt();
    >
    >You should *always* try to avoid uninitialized variables.


    That is why I call an initialisation routine.

    >> std::cout << MainInt << std::endl;
    >> return 0;
    >> }
    >>
    >> The intent of the function is to initialized its parm, so why
    >> bother initializing it first in main()? Unless, of course, it is not
    >> safe. Is it safe?

    >
    >It is *dangerous* because the variable may be used uninitialized.
    >If not by you, then by some poor programmer who must maintain your code.
    >Good programming habits will help keep you out of trouble.


    Initialising a variable twice is unclear. I try to avoid such
    confusions. Given a complex initialisation, I would note where the
    initialisation was dealt with.

    Sincerely,

    Gene Wirchenko
    Gene Wirchenko, Dec 17, 2003
    #12
  13. Gene Wirchenko wrote:

    > E. Robert Tisdale wrote:
    >
    >>This is poor programming practice. The following:
    >>
    >> int InitInt(void) {
    >> return 3;
    >> }
    >>
    >>would be much better.

    >
    > No, because this is only an example of initialisation.
    > For an arbitrarily complex initialisation,
    > there might be more than one parameter being initialised
    > and in such configuration that
    > it could not be combined into one structure
    > and thus would not be suitable for a return value.
    >
    >>You should *always* try to avoid uninitialized variables.

    >
    > That is why I call an initialisation routine.


    You should avoid any initialization routine except, perhaps,
    a private class member function to be called by a constructor.
    A method which is applied to an object after construction
    is a *modifier* and *not* an initializer.
    A *modifier* changes the object's *state*.
    You should try to design your classes
    so that objects can be declared const
    and initialized at the point where they are declared.
    This minimizes the number of variables
    that you need to keep track of in your program
    which makes your program easier for you and other programmers
    to read, understand and maintain.
    Container classes are an obvious exception.
    You can't do much with a const container.

    > Initialising a variable twice is unclear.
    >
    > I try to avoid such confusions. Given a complex initialisation,
    > I would note where the initialisation was dealt with.


    The best place to deal with [complicated] initialization
    is in a constructor. Subscribers to the comp.lang.c++ newsgroup
    can help you with designing constructors
    to completely initialize complicated objects.
    E. Robert Tisdale, Dec 17, 2003
    #13
  14. Gene Wirchenko

    Jason Heyes Guest

    "E. Robert Tisdale" <> wrote in message
    news:...
    > Gene Wirchenko wrote:
    >
    > > Is the following guaranteed safe?
    > >
    > > void InitInt(int & SomeInt) {
    > > SomeInt=3;
    > > return;
    > > }

    >
    > This is poor programming practice. The following:
    >
    > int InitInt(void) {
    > return 3;
    > }
    >
    > would be much better.
    >
    > >
    > > int main(int argc, char* argv[]) {
    > > int MainInt; // not initialized!
    > > InitInt(MainInt);

    >
    > int MainInt = InitInt();
    >
    > You should *always* try to avoid uninitialized variables.
    >
    > > std::cout << MainInt << std::endl;
    > > return 0;
    > > }
    > >
    > > The intent of the function is to initialized its parm, so why
    > > bother initializing it first in main()? Unless, of course, it is not
    > > safe. Is it safe?

    >
    > It is *dangerous* because the variable may be used uninitialized.
    > If not by you, then by some poor programmer who must maintain your code.
    > Good programming habits will help keep you out of trouble.
    >


    The fact of the matter is that MainInt *is* initialised, albeit to a
    meaningless value. What makes it bad practice is not that the initial value
    of MainInt is meaningless, but rather that the initial value of MainInt is
    never used. It is overwritten with a new value by InitInt(). Doesn't this
    spell bad programming practice?
    Jason Heyes, Dec 17, 2003
    #14
  15. Gene Wirchenko

    Jack Klein Guest

    On Thu, 18 Dec 2003 10:55:54 +1100, "Jason Heyes"
    <> wrote in alt.comp.lang.learn.c-c++:

    > "E. Robert Tisdale" <> wrote in message
    > news:...
    > > Gene Wirchenko wrote:
    > >
    > > > Is the following guaranteed safe?
    > > >
    > > > void InitInt(int & SomeInt) {
    > > > SomeInt=3;
    > > > return;
    > > > }

    > >
    > > This is poor programming practice. The following:
    > >
    > > int InitInt(void) {
    > > return 3;
    > > }
    > >
    > > would be much better.
    > >
    > > >
    > > > int main(int argc, char* argv[]) {
    > > > int MainInt; // not initialized!
    > > > InitInt(MainInt);

    > >
    > > int MainInt = InitInt();
    > >
    > > You should *always* try to avoid uninitialized variables.
    > >
    > > > std::cout << MainInt << std::endl;
    > > > return 0;
    > > > }
    > > >
    > > > The intent of the function is to initialized its parm, so why
    > > > bother initializing it first in main()? Unless, of course, it is not
    > > > safe. Is it safe?

    > >
    > > It is *dangerous* because the variable may be used uninitialized.
    > > If not by you, then by some poor programmer who must maintain your code.
    > > Good programming habits will help keep you out of trouble.
    > >

    >
    > The fact of the matter is that MainInt *is* initialised, albeit to a


    No, it is not. Not in the terms defined by the C++ standard. It is
    uninitialized and might indeed contain a trap representation, that is
    a bit pattern that does not represent a valid value for the object
    type.

    > meaningless value. What makes it bad practice is not that the initial value
    > of MainInt is meaningless, but rather that the initial value of MainInt is
    > never used. It is overwritten with a new value by InitInt(). Doesn't this
    > spell bad programming practice?


    There is no initial value to be unused. An uninitialized object has
    indeterminate. Any use of an indeterminate value produces undefined
    behavior.

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c /faq
    Jack Klein, Dec 18, 2003
    #15
  16. Gene Wirchenko

    Jason Heyes Guest

    "Jack Klein" <> wrote in message
    news:...
    > On Thu, 18 Dec 2003 10:55:54 +1100, "Jason Heyes"
    > <> wrote in alt.comp.lang.learn.c-c++:
    >
    > > "E. Robert Tisdale" <> wrote in message
    > > news:...
    > > > Gene Wirchenko wrote:
    > > >
    > > > > Is the following guaranteed safe?
    > > > >
    > > > > void InitInt(int & SomeInt) {
    > > > > SomeInt=3;
    > > > > return;
    > > > > }
    > > >
    > > > This is poor programming practice. The following:
    > > >
    > > > int InitInt(void) {
    > > > return 3;
    > > > }
    > > >
    > > > would be much better.
    > > >
    > > > >
    > > > > int main(int argc, char* argv[]) {
    > > > > int MainInt; // not initialized!
    > > > > InitInt(MainInt);
    > > >
    > > > int MainInt = InitInt();
    > > >
    > > > You should *always* try to avoid uninitialized variables.
    > > >
    > > > > std::cout << MainInt << std::endl;
    > > > > return 0;
    > > > > }
    > > > >
    > > > > The intent of the function is to initialized its parm, so why
    > > > > bother initializing it first in main()? Unless, of course, it is

    not
    > > > > safe. Is it safe?
    > > >
    > > > It is *dangerous* because the variable may be used uninitialized.
    > > > If not by you, then by some poor programmer who must maintain your

    code.
    > > > Good programming habits will help keep you out of trouble.
    > > >

    > >
    > > The fact of the matter is that MainInt *is* initialised, albeit to a

    >
    > No, it is not. Not in the terms defined by the C++ standard. It is
    > uninitialized and might indeed contain a trap representation, that is
    > a bit pattern that does not represent a valid value for the object
    > type.
    >
    > > meaningless value. What makes it bad practice is not that the initial

    value
    > > of MainInt is meaningless, but rather that the initial value of MainInt

    is
    > > never used. It is overwritten with a new value by InitInt(). Doesn't

    this
    > > spell bad programming practice?

    >
    > There is no initial value to be unused. An uninitialized object has
    > indeterminate. Any use of an indeterminate value produces undefined
    > behavior.
    >


    Oh well in that case it is simply wrong code. I wasn't aware that the C++
    standard was so strict with regard to initialised variables. Personally I
    never declare an object without initialising it - no matter what type it is.
    But let me ask you, does assigning a value to an uninitialised int result in
    undefined behavior? Thanks.
    Jason Heyes, Dec 18, 2003
    #16
  17. Gene Wirchenko

    tom_usenet Guest

    On Thu, 18 Dec 2003 17:43:01 +1100, "Jason Heyes"
    <> wrote:

    >> No, it is not. Not in the terms defined by the C++ standard. It is
    >> uninitialized and might indeed contain a trap representation, that is
    >> a bit pattern that does not represent a valid value for the object
    >> type.
    >>
    >> > meaningless value. What makes it bad practice is not that the initial

    >value
    >> > of MainInt is meaningless, but rather that the initial value of MainInt

    >is
    >> > never used. It is overwritten with a new value by InitInt(). Doesn't

    >this
    >> > spell bad programming practice?

    >>
    >> There is no initial value to be unused. An uninitialized object has
    >> indeterminate. Any use of an indeterminate value produces undefined
    >> behavior.
    >>

    >
    >Oh well in that case it is simply wrong code. I wasn't aware that the C++
    >standard was so strict with regard to initialised variables. Personally I
    >never declare an object without initialising it - no matter what type it is.
    >But let me ask you, does assigning a value to an uninitialised int result in
    >undefined behavior? Thanks.


    No. Only using an indeterminate value as an rvalue is undefined
    behaviour. Using is as an lvalue (in, say, an assignment or binding to
    a reference as in the OP's code) is fine.

    Tom

    C++ FAQ: http://www.parashift.com/c -faq-lite/
    C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
    tom_usenet, Dec 18, 2003
    #17
  18. Gene Wirchenko

    Jason Heyes Guest

    "tom_usenet" <> wrote in message
    news:...
    > On Thu, 18 Dec 2003 17:43:01 +1100, "Jason Heyes"
    > <> wrote:
    > >
    > >Oh well in that case it is simply wrong code. I wasn't aware that the C++
    > >standard was so strict with regard to initialised variables. Personally I
    > >never declare an object without initialising it - no matter what type it

    is.
    > >But let me ask you, does assigning a value to an uninitialised int result

    in
    > >undefined behavior? Thanks.

    >
    > No. Only using an indeterminate value as an rvalue is undefined
    > behaviour. Using is as an lvalue (in, say, an assignment or binding to
    > a reference as in the OP's code) is fine.
    >
    > Tom
    >
    > C++ FAQ: http://www.parashift.com/c -faq-lite/
    > C FAQ: http://www.eskimo.com/~scs/C-faq/top.html


    Cool. :)
    Jason Heyes, Dec 18, 2003
    #18
  19. Gene Wirchenko

    Greg Comeau Guest

    In article <3fe14c78$0$18388$>,
    Jason Heyes <> wrote:
    >Jack Klein wrote:
    >> > never used. It is overwritten with a new value by InitInt().
    >> > Doesn't this spell bad programming practice?

    >>
    >> There is no initial value to be unused. An uninitialized object has
    >> indeterminate. Any use of an indeterminate value produces undefined
    >> behavior.
    >>

    >Oh well in that case it is simply wrong code. I wasn't aware that the C++
    >standard was so strict with regard to initialised variables.


    As is C.

    >Personally I
    >never declare an object without initialising it - no matter what type it is.


    That's a very good rule of thumb, but if I'm understanding you,
    forcing an initialization can often be awkward.

    >But let me ask you, does assigning a value to an uninitialised int result in
    >undefined behavior? Thanks.


    No, because that's not a use of the indeterminate value.
    --
    Greg Comeau/4.3.3:Full C++03 core language + more Windows backends
    Comeau C/C++ ONLINE ==> http://www.comeaucomputing.com/tryitout
    World Class Compilers: Breathtaking C++, Amazing C99, Fabulous C90.
    Comeau C/C++ with Dinkumware's Libraries... Have you tried it?
    Greg Comeau, Dec 18, 2003
    #19
  20. Greg Comeau wrote:

    > Jason Heyes wrote:
    >
    >>Personally, I never declare an object without initializing it --
    >>no matter what type it is.

    >
    > That's a very good rule of thumb, but if I'm understanding you,
    > forcing an initialization can often be awkward.


    Not very often
    but I'll give an example where it is awkward -- containers:

    int a[n];
    for (int j = 0; j < n; ++j)
    cin >> a[n];

    Unless they are small, const containers can be awkward to initialize:

    const int a[] = {0, 1, 2, 3};

    Well, you get the idea. You can do this:

    class wrapper {
    private:
    int a[n];
    public:
    const
    int& operator[](int j) const { return a[j]; }
    int& operator[](int j) { return a[j]; }
    wrapper(std::istream& is) {
    for (int j = 0; j < n; ++j)
    is >> a[n];
    }
    };

    then this:

    const wrapper a(cin);

    Of course, this can cause a problem,
    if the constructor encounters an exception while reading from cin.
    Is this awkward? Problematic?
    I suspect that you would say yes.
    E. Robert Tisdale, Dec 18, 2003
    #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. dee
    Replies:
    9
    Views:
    498
    Joseph Byrns
    Apr 15, 2005
  2. Andy Fish
    Replies:
    7
    Views:
    545
    David Carlisle
    Jan 10, 2005
  3. Anand
    Replies:
    2
    Views:
    890
    Anand
    Sep 11, 2003
  4. Replies:
    2
    Views:
    276
    Rolf Magnus
    Feb 4, 2007
  5. Replies:
    2
    Views:
    285
    John Ratliff
    Feb 4, 2007
Loading...

Share This Page