Thread: Idea for new language construct

  1. #1
    Confused Magos's Avatar
    Join Date
    Sep 2001
    Location
    Sweden
    Posts
    3,145

    Idea for new language construct

    Many times when writing functions/methods I've wanted some kind of function-destructor concept. A piece of code that always runs when returning no matter where you're returning from. Of course similar effects can be done using smart pointers, additional function calls etc... but it'd be nice to have an easy-to-use buildt-in construct for this.

    The basic structural idea:
    Code:
    int Func()
    {
      first
      {
        int* x = new int(1337)
    
        if(Something()) return 0
        if(SomethingElse()) return 0
        if(YetSomethingElse()) return 0
    
        return *x
      }
      then
      {
        delete x
      }
    }
    The function-destructor is called after the return value has been pushed to the stack so the dereference (*x) will be safe. You won't be able to use return-statements in the destructor as it would screw things up.

    Comments? Do you think this would make a useful addition?
    MagosX.com

    Give a man a fish and you feed him for a day.
    Teach a man to fish and you feed him for a lifetime.

  2. #2
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >Comments? Do you think this would make a useful addition?
    Something like a finally block for functions? I honestly don't see the need for it when you can achieve the same effect with RAII and a little planning.
    My best code is written with the delete key.

  3. #3
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    I'm not sure Magos.

    Some compilers already implement that through function attributes, if I recall correctly, and that is probably how I would like best to have it implemented as a standard if it ever came to see the light of day.

    Code:
    void foo(){   /*... */   }  //function definition
    
    void foo() __attribute__((destructor()) { /*... */ } //function destructor definition
    I think that would better match how destructors and constructors are used in classes. A first-then statement is perhaps too surprising since the flow of the code is afffected in ways you haven't seen before in C++.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  4. #4
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    I agree with Prelude. The try...finally construct in Java and C#, which does what you want, is a crutch developed to make up for the lack of deterministic object destruction.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  5. #5
    Registered User jlou's Avatar
    Join Date
    Jul 2003
    Posts
    1,090
    Code:
    int Func()
    {
      struct cleaner
      {
        cleaner(int* x_) : x(x_) {}
        ~cleaner() { delete x; }
        int* x;
      } c(new int(1337));
    
      if(Something()) return 0;
      if(SomethingElse()) return 0;
      if(YetSomethingElse()) return 0;
    
      return *c.x;
    }
    Obviously this is the same as using a smart pointer, but I think new additions to the language will make these kinds of thing more streamlined and possibly as easy to use as a finally block for more indiviual and unique cases.

  6. #6
    Confused Magos's Avatar
    Join Date
    Sep 2001
    Location
    Sweden
    Posts
    3,145
    As I mentioned smart pointers *could* be used instead, but to give a sligtly different example:
    Code:
    bool PerformTasks()
    {
      first
      {
        if(!Task1()) return false;
        if(!Task2()) return false;
        if(!Task3()) return false;
        if(!Task4()) return false;
        if(!Task5()) return false;
        if(!Task6()) return false;
    
        return true;
      }
      then
      {
        Cleanup();
      }
    }
    Without duplicating the call to Cleanup, without having hugely nested if-statements and without having a huge if-test I see no clean and efficient way of performing this task.
    MagosX.com

    Give a man a fish and you feed him for a day.
    Teach a man to fish and you feed him for a lifetime.

  7. #7
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Code:
    bool PerformTasks()
    {
      struct sentinel { ~sentinel() { Cleanup(); } } s;
    
      if(!Task1()) return false;
      if(!Task2()) return false;
      if(!Task3()) return false;
      if(!Task4()) return false;
      if(!Task5()) return false;
      if(!Task6()) return false;
    
      return true;
    }
    And the code isn't even more indented (something I don't like about try...catch).
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  8. #8
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    You don't need a finalizer if you can manage memory properly.

  9. #9
    Reverse Engineer maxorator's Avatar
    Join Date
    Aug 2005
    Location
    Estonia
    Posts
    2,318
    Doesn't C++ free memory under non-static variables in functions???
    "The Internet treats censorship as damage and routes around it." - John Gilmore

  10. #10
    Confused Magos's Avatar
    Join Date
    Sep 2001
    Location
    Sweden
    Posts
    3,145
    The idea here was to suggest a construct that *might* or *might not* be useful in certain situations, simplify syntax and/or as an alternative. As an example in C++ you can do:
    Code:
    int a, b, c;
    Though entirely pointless as you can just do:
    Code:
    int a;
    int b;
    int c;
    It's still there for basically the same reasons as above. And for the record I'm not trying to claim my construct is the one truth. I asked for opinions, and I got them. Thanks.
    MagosX.com

    Give a man a fish and you feed him for a day.
    Teach a man to fish and you feed him for a lifetime.

  11. #11
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    Quote Originally Posted by Magos
    As I mentioned smart pointers *could* be used instead, but to give a sligtly different example:
    Code:
    bool PerformTasks()
    {
      first
      {
        if(!Task1()) return false;
        if(!Task2()) return false;
        if(!Task3()) return false;
        if(!Task4()) return false;
        if(!Task5()) return false;
        if(!Task6()) return false;
    
        return true;
      }
      then
      {
        Cleanup();
      }
    }
    Without duplicating the call to Cleanup, without having hugely nested if-statements and without having a huge if-test I see no clean and efficient way of performing this task.
    In C (and C++, not using RAII), the "goto cleanup" pattern is commonly used:
    Code:
    bool PerformTasks()
    {
        bool fSuccess = false;
    
        if(!Task1()) goto cleanup;
        if(!Task2()) goto cleanup;
        if(!Task3()) goto cleanup;
        if(!Task4()) goto cleanup;
        if(!Task5()) goto cleanup;
        if(!Task6()) goto cleanup;
    
        fSuccess = true;
    
    cleanup:
        Cleanup();
        return fSuccess;
    }
    Example

    Your construct would essentially provide a nice syntax for this pattern. In C++ RAII is considered ideal, while C has been using this pattern for decades, so there is unlikely to be much support for introducing a new construct in either language.

  12. #12
    {Jaxom,Imriel,Liam}'s Dad Kennedy's Avatar
    Join Date
    Aug 2006
    Location
    Alabama
    Posts
    1,065
    Quote Originally Posted by maxorator
    Doesn't C++ free memory under non-static variables in functions???
    I don't understand exactly what you mean by this, but if this was the case, then you wouldn't be able to dynamically define an array under a method without having it vanish.

    If you mean does it clean up for you on close, the OS *may* do this for you, however, I remember the days when one would have to reboot her/his computer because some POC program ate memory and didn't free it.

  13. #13
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    For each new there must be a delete. Always.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  14. #14
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    ..and each malloc a free.

    It's actually quite simple.

  15. #15
    Reverse Engineer maxorator's Avatar
    Join Date
    Aug 2005
    Location
    Estonia
    Posts
    2,318
    Quote Originally Posted by Mario F.
    For each new there must be a delete. Always.
    I never use new
    "The Internet treats censorship as damage and routes around it." - John Gilmore

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. d programming language - a better c++?
    By kypronite in forum Tech Board
    Replies: 12
    Last Post: 02-28-2011, 02:55 AM
  2. Why C Matters
    By DavidP in forum A Brief History of Cprogramming.com
    Replies: 136
    Last Post: 01-16-2008, 09:09 AM
  3. Language
    By nvoigt in forum A Brief History of Cprogramming.com
    Replies: 19
    Last Post: 04-29-2002, 02:28 PM
  4. bubble sort in assembly language!!!!!!
    By lorenzohhh in forum C++ Programming
    Replies: 1
    Last Post: 04-15-2002, 08:30 PM
  5. Natural Language Parsing
    By edk in forum C++ Programming
    Replies: 7
    Last Post: 04-12-2002, 07:06 PM