FAQ
I find myself rather often write

func main() {
os.Exit(mymain())
}

because main doesn't return a status to the os. And calling os.Exit(status)
in main is not a good idea as deferred functions wont fire. Much to late
for a change?

--

Search Discussions

  • Minux at Dec 20, 2012 at 6:23 pm

    On Fri, Dec 21, 2012 at 12:04 AM, Johann Höchtl wrote:

    I find myself rather often write

    func main() {
    os.Exit(mymain())
    }

    because main doesn't return a status to the os. And calling
    os.Exit(status) in main is not a good idea as deferred functions wont fire.
    Much to late for a change?
    I think the returned status is OS-specific, and so Go the language should
    not define its type
    (Maybe some OS can only report 8-bit result while some other OS support
    arbitrary string
    as program status, there is considerable differences between that; there
    might even be
    environment that don't support returning status code or the concept of
    status code simply
    doesn't exist)

    I imagine some Plan 9 users might be disagree with the signature of
    os.Exit().

    --
  • Johann Höchtl at Dec 20, 2012 at 10:18 pm

    On 12/20/2012 07:23 PM, minux wrote:
    On Fri, Dec 21, 2012 at 12:04 AM, Johann Höchtl
    wrote:

    I find myself rather often write

    func main() {
    os.Exit(mymain())
    }

    because main doesn't return a status to the os. And calling
    os.Exit(status) in main is not a good idea as deferred functions
    wont fire. Much to late for a change?

    I think the returned status is OS-specific, and so Go the language
    should not define its type
    (Maybe some OS can only report 8-bit result while some other OS support
    arbitrary string
    as program status, there is considerable differences between that; there
    might even be
    environment that don't support returning status code or the concept of
    status code simply
    doesn't exist)

    I imagine some Plan 9 users might be disagree with the signature of
    os.Exit().
    That may be the case. But package os is a compromise anyway and we have
    os.Exit only taking ints right now. Extending main as in C to return an
    int flag to the spawning process would help especially in the case of
    small routines embedded in shell scripts.

    --
  • Minux at Dec 20, 2012 at 10:29 pm

    On Friday, December 21, 2012, Johann Höchtl wrote:
    On 12/20/2012 07:23 PM, minux wrote:


    On Fri, Dec 21, 2012 at 12:04 AM, Johann Höchtl
    wrote:

    I find myself rather often write

    func main() {
    os.Exit(mymain())
    }

    because main doesn't return a status to the os. And calling
    os.Exit(status) in main is not a good idea as deferred functions
    wont fire. Much to late for a change?

    I think the returned status is OS-specific, and so Go the language
    should not define its type
    (Maybe some OS can only report 8-bit result while some other OS support
    arbitrary string
    as program status, there is considerable differences between that; there
    might even be
    environment that don't support returning status code or the concept of
    status code simply
    doesn't exist)

    I imagine some Plan 9 users might be disagree with the signature of
    os.Exit().
    That may be the case. But package os is a compromise anyway and we have
    os.Exit only taking ints right now. Extending main as in C to return an int
    flag to the spawning process would help especially in the case of small
    routines embedded in shell scripts.
    i think changing standard library has a lower cost compared to changing the
    core language.

    you will note the the language does a good amount of work to avoid
    architecture
    or os dependencies. for example, even the lock is implemented in standard
    library
    because it is highly architecture dependent (future architectures might use
    entirely
    different form of locks or atomics, if that happens, we only need to revise
    the std.
    lib., and the core language doesn't need to be changed.)

    you can also feel this when you read the memory model docs, because for
    people
    accustomed to programming on x86, some clauses of mem. model is simply crazy
    or unreasonable, yet some architectures implementations do do those
    unreasonable
    things to achieve better efficiency.

    --
  • Kyle Lemons at Dec 20, 2012 at 10:29 pm
    What's wrong with just calling os.Exit with a nonzero code when you have a
    failure in main?

    On Thu, Dec 20, 2012 at 5:18 PM, Johann Höchtl wrote:
    On 12/20/2012 07:23 PM, minux wrote:


    On Fri, Dec 21, 2012 at 12:04 AM, Johann Höchtl
    <johann.hoechtl@gmail.com <mailto:johann.hoechtl@gmail.**com<johann.hoechtl@gmail.com>>>
    wrote:

    I find myself rather often write

    func main() {
    os.Exit(mymain())
    }

    because main doesn't return a status to the os. And calling
    os.Exit(status) in main is not a good idea as deferred functions
    wont fire. Much to late for a change?

    I think the returned status is OS-specific, and so Go the language
    should not define its type
    (Maybe some OS can only report 8-bit result while some other OS support
    arbitrary string
    as program status, there is considerable differences between that; there
    might even be
    environment that don't support returning status code or the concept of
    status code simply
    doesn't exist)

    I imagine some Plan 9 users might be disagree with the signature of
    os.Exit().
    That may be the case. But package os is a compromise anyway and we have
    os.Exit only taking ints right now. Extending main as in C to return an int
    flag to the spawning process would help especially in the case of small
    routines embedded in shell scripts.

    --

    --
  • Minux at Dec 20, 2012 at 10:33 pm

    On Friday, December 21, 2012, Kyle Lemons wrote:

    What's wrong with just calling os.Exit with a nonzero code when you have a
    failure in main?
    i'd like to add that the go command itself uses code like that to
    implement a localized atexit functionality.

    --
  • Johann Höchtl at Dec 20, 2012 at 10:56 pm

    Am 20.12.2012 23:29 schrieb "Kyle Lemons" <kevlar@google.com>:
    What's wrong with just calling os.Exit with a nonzero code when you have
    a failure in main?
    >
    deferred calls will not fire
    On Thu, Dec 20, 2012 at 5:18 PM, Johann Höchtl wrote:
    On 12/20/2012 07:23 PM, minux wrote:


    On Fri, Dec 21, 2012 at 12:04 AM, Johann Höchtl
    wrote:

    I find myself rather often write

    func main() {
    os.Exit(mymain())
    }

    because main doesn't return a status to the os. And calling
    os.Exit(status) in main is not a good idea as deferred functions
    wont fire. Much to late for a change?

    I think the returned status is OS-specific, and so Go the language
    should not define its type
    (Maybe some OS can only report 8-bit result while some other OS support
    arbitrary string
    as program status, there is considerable differences between that; there
    might even be
    environment that don't support returning status code or the concept of
    status code simply
    doesn't exist)

    I imagine some Plan 9 users might be disagree with the signature of
    os.Exit().

    That may be the case. But package os is a compromise anyway and we have
    os.Exit only taking ints right now. Extending main as in C to return an int
    flag to the spawning process would help especially in the case of small
    routines embedded in shell scripts.

    --
    --
  • Andrew Gerrand at Dec 20, 2012 at 11:04 pm
    Say the signature of main is "func main() int", where the return value is
    the process exit code, and os.Exit doesn't exist.

    What does a function that is not main do to exit the program? For example,
    flag.Parse calls os.Exit(2) if the flags are parsed incorrectly. Would you
    need to set up a deferred recover in main, and panic from flag.Parse? That
    has different semantics, though. Would you have flag.Parse return an error?
    But then you'd need to call flag.Usage and exit manually, which is
    inconvenient.

    I suspect that whatever the proposed solution to this problem is, it will
    be more complicated than the status quo.

    Andrew

    --
  • Johann Höchtl at Dec 20, 2012 at 11:16 pm
    I see the pattern / bigger underlying 'issue'. That might be the reason why
    there is no atexit too. Thinking about it I can't propose a better solution
    either.
    Am 21.12.2012 00:04 schrieb "Andrew Gerrand" <adg@golang.org>:
    Say the signature of main is "func main() int", where the return value is
    the process exit code, and os.Exit doesn't exist.

    What does a function that is not main do to exit the program? For example,
    flag.Parse calls os.Exit(2) if the flags are parsed incorrectly. Would you
    need to set up a deferred recover in main, and panic from flag.Parse? That
    has different semantics, though. Would you have flag.Parse return an error?
    But then you'd need to call flag.Usage and exit manually, which is
    inconvenient.

    I suspect that whatever the proposed solution to this problem is, it will
    be more complicated than the status quo.

    Andrew
    --
  • Yy at Dec 20, 2012 at 11:53 pm

    On 20 December 2012 17:04, Johann Höchtl wrote:

    I find myself rather often write

    func main() {
    os.Exit(mymain())
    }
    (Maybe you already thought on this, but just in case.)

    Another option, which probably is not a big improvement but may be simpler
    in some cases, is to defer os.Exit:

    func main() {
    var exit int // or exit := 0
    defer os.Exit(exit)
    // do whatever you want and set exit
    }


    --
    - yiyus || JGL .

    --
  • Yy at Dec 20, 2012 at 11:59 pm

    On 21 December 2012 00:53, yy wrote:
    func main() {
    var exit int // or exit := 0
    defer os.Exit(exit)
    // do whatever you want and set exit
    }
    Sorry. Of course, this won't work, because the arguments are evaluated when
    you call defer.

    However, a function which takes a pointer may be useful:

    func exit(e *int) {
    os.Exit(*e)
    }

    but, yeah, at that point is not an improvement at all. Sorry for the noise.


    --
    - yiyus || JGL .

    --
  • Jesse McNelis at Dec 21, 2012 at 2:53 am

    On Fri, Dec 21, 2012 at 10:59 AM, yy wrote:

    Sorry. Of course, this won't work, because the arguments are evaluated
    when you call defer.

    However, a function which takes a pointer may be useful:

    func exit(e *int) {
    os.Exit(*e)
    }
    func main() {
    ret := -1
    defer func(){os.Exit(ret)}
    ret = mymain()
    return
    }

    Although, this would exit before a panic could be printed, so if you don't
    want your panics disappearing you'd need to add a recover and check for the
    panic before running the os.Exit().




    --
    =====================
    http://jessta.id.au

    --
  • Daniel D Weston at Dec 21, 2012 at 12:27 am
    Deferred functions fire LIFO, so if you add at the very beginning of main()
    a deferred function call that recovers, parses any panic into an exit code,
    then calls os.Exit, it should fire last after all other deferred functions
    are done.
    On Thursday, December 20, 2012 8:04:17 AM UTC-8, Johann Höchtl wrote:

    I find myself rather often write

    func main() {
    os.Exit(mymain())
    }

    because main doesn't return a status to the os. And calling
    os.Exit(status) in main is not a good idea as deferred functions wont fire.
    Much to late for a change?
    --
  • Sonia Keys at Dec 22, 2012 at 1:12 pm
    http://soniacodes.wordpress.com/2011/04/28/deferred-functions-and-an-exit-code/
    On Thursday, December 20, 2012 11:04:17 AM UTC-5, Johann Höchtl wrote:

    I find myself rather often write

    func main() {
    os.Exit(mymain())
    }

    because main doesn't return a status to the os. And calling
    os.Exit(status) in main is not a good idea as deferred functions wont fire.
    Much to late for a change?
    --

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedDec 20, '12 at 4:04p
activeDec 22, '12 at 1:12p
posts14
users8
websitegolang.org

People

Translate

site design / logo © 2022 Grokbase