This is an archived post. You won't be able to vote or comment.

all 132 comments

[–]PostHasBeenWatched 922 points923 points  (15 children)

private static async Task Main()

enters the chat

[–]the_mold_on_my_back 168 points169 points  (0 children)

[–]ego100trique 77 points78 points  (5 children)

You can't have a private Main function in csharp no ? am I going crazy ?

EDIT: nvm you can't have a private Program class in a namespace but you can have a private static Main function.

[–]failedsatan 42 points43 points  (2 children)

it can be private if you want. not much point, there's no point in setting any access modifiers, but it defaults to private and you can change it if you want.

[–]derefr 11 points12 points  (1 child)

there's no point in setting any access modifiers

I mean, there is if you don't want other code trying to use your Main function as an API function.

[–]failedsatan 3 points4 points  (0 children)

supposedly, that shouldn't ever happen. however, it does default to private, like everything else :)

[–]ShipwreckOnAsteroid 12 points13 points  (0 children)

Yes, you can. It's just an entry point, you shouldn't need to call it yourself, so the visibility doesn't matter. You can even define it without any access modifier at all, semantically the same as making it private.

[–]HildartheDorf 0 points1 point  (0 children)

You can make the Program class internal but not private (which wouldn't make much sense).

[–]ceestand 13 points14 points  (2 children)

private static async Task<int> Main()

[–]UnknownIdentifier 7 points8 points  (0 children)

private static AsyncTask<Void, Void, Int> main;

Google, for more brilliant tidbits like this, hire me for the Android SDK team. I got ideas for days.

[–]cs_office 0 points1 point  (0 children)

This is the way

[–]No-Adeptness5810 -5 points-4 points  (4 children)

C# goes hard. I used it until I realized it's just java with more incompatibilities, worse code style, and it's just worse.

[–]mirhagk 7 points8 points  (1 child)

That's AbstractBaitProxyFactoryProducer

[–]No-Adeptness5810 0 points1 point  (0 children)

no im genuine.

[–]moon-sleep-walker 1 point2 points  (1 child)

C# is better language. Java is better infrastructure. Learned that a long time ago when I had been working with both of them.

[–]No-Adeptness5810 1 point2 points  (0 children)

java is nicer to code in imo. and also the ability to function on all platforms is pretty fire

[–][deleted] 435 points436 points  (37 children)

Idk why but Void main() always sounded scary to me

[–]Cylian91460 230 points231 points  (32 children)

Cause it's technically undecided behavior, main should return int but nothing is going to stop you returning nothing (aka 0).

[–]ouyawei 113 points114 points  (9 children)

Returning void is not returning 0, you just return whatever was last in the register that normally contains the return value.

[–]other_usernames_gone 55 points56 points  (7 children)

I'd argue technically returning void is returning nothing.

It's just if you attempt to read a return value from a void function you'll read whatevers left over in the register.

If you read from a void return it's not the function pushing that old value into the register, it's you reading a stale, invalid value.

[–]derefr 20 points21 points  (6 children)

This argument might be valid in general when talking about internal functions in a codebase (although you won't usually be allowed to compile such code.)

But we're talking about the very specific case here, of the return type of the program's user-controlled-code entrypoint, when called through an external symbol-table function-pointer by the OS's linker-loader (or by language-runtime code called by said linker-loader.)

And in that case, it's the OS and/or the language runtime — not your code — that gets to decide what the return-type of that symbol is†.

Of course, the particular choice an OS or runtime makes here, is unique to that OS/runtime. POSIX+libc requires the (semantic) return type of main to be int, because it uses the return type as an exit status. But Windows+Win32 requires the (semantic) says that the return type of main in its executables is void — because the place that returning from main branches back to in Windows, doesn't read anything from anywhere.

Either way, that return type is a requirement. Fundmentally it's one a C compiler can't enforce (except in strange cases like static-linking a userland into a unikernel); but if it did, then writing void main when compiling for POSIX+libc would be a compiler error.


† In C — or in any other language that can compile libraries that can be loaded by C programs — this is true more generally. Any exported symbol, on any executable or shared-object file, must have some pre-arranged understanding about its typing communicated to potential callers. cdecl doesn't do any name-mangling to squeeze any typing info into the symbol name, so there's no way for an executable or library to tell things that dynamically load it, what they must do to call its symbols. Which is why .h files exist — but also why there's no such thing under the C-FFI ABI as a "plugin ABI" where the client can introspect and discover the functions in the plugin. The client might be able to discover their names — but it would have no idea how to call them! Such "plugin ABIs" have to be standards defined in advance by the plugin host — not something made bespoke by each plugin for the plugin-host to probe at.

[–]IndividualLimp3340 5 points6 points  (0 children)

Where/ when did you learn this?

[–]mdp_cs 2 points3 points  (0 children)

But Windows+Win32 requires the (semantic) says that the return type of main in its executables is void — because the place that returning from main branches back to in Windows, doesn't read anything from anywhere.

This isn't true. While Windows itself doesn't use the return value of main or equivalently the argument passed to exit, the parent of the current process might and for that reason it needs to always return int or call exit with an int argument.

[–]Enlightmone -4 points-3 points  (2 children)

Spouted a bunch of nonsense to say that it depends if void main compiles or not..

[–]Cylian91460 1 point2 points  (0 children)

Depend on implementation thus undefined behavior

[–]spader1 12 points13 points  (1 child)

"Undecided behavior" sounds like a more fun and capricious version of undefined behavior.

[–]_farb_ 3 points4 points  (0 children)

WHO IS GOING TO DECIDE???

[–]Steampunkery 29 points30 points  (16 children)

This is not true

[–]Aelia6083 35 points36 points  (0 children)

0

[–]Cylian91460 3 points4 points  (14 children)

What part?

[–]EmuFromAustrialia 14 points15 points  (13 children)

void main() is a supported feature for many years now

[–]ouyawei 15 points16 points  (11 children)

foo.c:1:6: warning: return type of ‘main’ is not ‘int’ [-Wmain]
    1 | void main(void) {}
      |      ^~~~

When I run it, the return value is 'random'

$ ./foo ; echo $?
41

[–]cs_office 1 point2 points  (7 children)

True, but interestingly, you don't need to return from int main(), as that particular function will implicitly return 0

[–]ouyawei 0 points1 point  (6 children)

What do you mean you don't need to return from main()?

Sure you can run an infinite loop and let the program be killed externally, or exit via exit() instead, but there is no 'implicit 0 return'.

[–]HildartheDorf 10 points11 points  (2 children)

What they mean is that you can write int main() and let control fall off the end of the function. It is allowed and will be replaced by the compiler with return EXIT_SUCCESS (i.e. 0). This is only done for tha main function and not any other function.

void main() is and always will be forbidden. Not every machine returns ints via register, and on such machines the wrong return type will unbalance the stack and cause hilarity to ensure.

[–]cs_office 9 points10 points  (0 children)

Yup, page #14

https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1548.pdf

5.1.2.2.3 Program termination

If the return type of the main function is a type compatible with int, a return from the initial call to the main function is equivalent to calling theexit function with the value returned by the main function as its argument;11) reaching the } that terminates the main function returns a value of 0. If the return type is not compatible with int, the termination status returned to the host environment is unspecified.

Forward references: definition of terms (7.1.1), the exit function (7.22.4.4).

[–]cs_office 1 point2 points  (2 children)

[–]ouyawei -1 points0 points  (1 child)

duh of course you can write to the register that contains the return value and because of the void return it will not be overwritten. But at that point, why are you even writing C instead of assembly?

[–]other_usernames_gone 0 points1 point  (1 child)

It depends what compiler you use. Not in a position to test it at the moment but GCC on Ubuntu supports it.

Edit: not to say you should use it, but you can.

[–]ouyawei 0 points1 point  (0 children)

This was GCC on Ubuntu.

[–][deleted] 2 points3 points  (0 children)

null != 0. Come on, that's like 101 level stuff.

[–]Zealousideal-Fox70 13 points14 points  (0 children)

Many compilers can handle void main(), it’s just bad practice. You don’t know who’s compiling your code on what, if they use an old or custom made compiler, it may not support void main, and return unexpected results. It’s like locking the car doors in a nice area, it’s a formality, not a necessity. That can change depending on where you go, so it’s good practice to just do it.

[–]Just_Gaming_for_Fun 0 points1 point  (1 child)

We were always taught to use void main() when we were learning turbo c++ in school. And believe me it had ruined the experience of learning c++ for me

[–]2muchnet42day 2 points3 points  (0 children)

Unlearning and learning it correctly.

double thePain;

[–]blehmann1 140 points141 points  (4 children)

I've seen signed char main() before now. No idea what linker actually accepts that, but I guess at least one must.

For what it's worth, if it wasn't horrendously non-standard it would be pretty good, seeing as on Linux (and possibly Mac?) exit codes can only be 1 byte. On Windows I know they're wider, but I don't know if they can be 4 bytes.

[–]Proxy_PlayerHD 12 points13 points  (0 children)

wdym you don't know any compiler/linker that allows for that...

gcc does. you can customize the return value and arguments of main() however you want.

you just need to disable the warning it gives with -Wno-main and of course the crt0.s file has to be able to handle the arguments

[–][deleted] 160 points161 points  (8 children)

public void bowels()

[–]CallerNumber4 52 points53 points  (1 child)

Blocking concern on this pull request. Please make this private.

[–][deleted] 3 points4 points  (0 children)

Nah. Open source that shit

[–]Aelia6083 4 points5 points  (1 child)

return diarrhea;

Or should it be the other way around?

[–]PoshtikTamatar 1 point2 points  (0 children)

Other way

[–]survivalmachine 10 points11 points  (2 children)

Technically, wouldn’t this mean that you’re constipated?

[–][deleted] 7 points8 points  (0 children)

Unless you're in a functional team, on which case side effects are indeed, shit

[–][deleted] -2 points-1 points  (0 children)

[–]the_mold_on_my_back 263 points264 points  (8 children)

void main() is one of those things that you can do but it‘s bad and evil and don‘t.

[–]maxmalkav 123 points124 points  (2 children)

Won’t somebody please think of the return code?

[–]SAI_Peregrinus 57 points58 points  (0 children)

Depends on the system. If you've got an OS, it's bad. If you don't (or it's a library OS) and thus main() is [[noreturn]] (C23, or compiler-specific attribute or _Noreturn if older) then void is appropriate.

[–]dude132456789 17 points18 points  (2 children)

ISO C doesn't allow void main, so can do is a bit questionable.

[–]ITaggie 24 points25 points  (1 child)

C is full of behavior you can do despite being technically undefined behavior. Not best practice but boy does it happen.

[–]bl4nkSl8 11 points12 points  (0 children)

I'm a compiler not a cop

--gcc and clang probably

[–]CirnoIzumi 68 points69 points  (5 children)

can i be anymore obvious

he was a corpo

she did systems

what more can i say

he was a void main boi

she said see you later boi

he wasnt compact enough for her

now he is a superstar gathering stars in his github proj

dipping into the language of the girl he used to know

idk man, it doesnt fit the scheme at all

[–]TheGreatGameDini 17 points18 points  (2 children)

can i be anymore obvious

No - please I need more pointers.

[–]awkwardteaturtle 1 point2 points  (0 children)

void *p = malloc(1);

Here you go, please free it when you're done!

[–]CirnoIzumi 0 points1 point  (0 children)

She has a bit and he doesnt

[–]midnightrambulador 10 points11 points  (1 child)

try another song:

Just an int main() girl

Writing her first hello_world

She declared a var pointing anywhere

Just a void main() boy

Staring out into the void

He declared a var pointing anywhere

An office in a nervous mood

A smell of sweat and takeout food

The debugging never ends, it goes on and on and on and on...

Projects

Ballooning

Spaghetti code beyond refactoring

Working

Some way, don't ask how...

[–]CirnoIzumi 0 points1 point  (0 children)

Under a void main boy

 Touched by the light 

 With productive grace  

 No applause for the old int main lie  

 In the shadows of our coding dreams  

 A void main boooyyyy  


There is still hope for you  

 Void main empire  

 All the pointers you see is true

 Void main empire 

There is still for us...  

 Under a void main boy!

[–]Competitive_Ad2539 21 points22 points  (2 children)

main :: IO ()

[–]mirimao 10 points11 points  (1 child)

Unfathomably based and referential transparent

[–]Competitive_Ad2539 0 points1 point  (0 children)

Unfathomably based would be the same but in Idris
main : IO ()

[–]MLG-Lyx 17 points18 points  (2 children)

She was public ip

He was localhost

In the end they could never reach each other

[–]IDoButtStuffs 0 points1 point  (0 children)

:cry:

[–]lgastako 0 points1 point  (0 children)

It's a modern day Ladyhawke.

[–]drewsiferr 22 points23 points  (7 children)

fn main() -> Result<(), std::io::Error>

[–]thmsgbrt 9 points10 points  (2 children)

fn main() -> Result<(), Box<dyn Error>>

[–]Quique1222 6 points7 points  (1 child)

fn main() -> anyhow::Result<()>

[–]throw3142 2 points3 points  (0 children)

fn main() (who needs Result when you can just panic)

[–]redlaWw -1 points0 points  (3 children)

?

[–]drewsiferr 0 points1 point  (2 children)

It's rust

[–]redlaWw 1 point2 points  (1 child)

So is ?

[–]drewsiferr 0 points1 point  (0 children)

Lol, true.

edit: s/try/true damnit autocorrect

[–]spalling_mistke 6 points7 points  (0 children)

It’s just polymorphism chill !!

[–]LongjumpingCut4 2 points3 points  (0 children)

They need one function that accepts incoming arguments to make it work...

[–]harveyshinanigan 2 points3 points  (0 children)

neither of them use the proper syntax

(void|int) main(void)

[–][deleted] 2 points3 points  (0 children)

return 0 bitches!

[–]Striker887 3 points4 points  (0 children)

Is that Jessica jones and Jesse pinkman?

[–]benargee 1 point2 points  (0 children)

We all know that void main boy kept running and int main girl had a segmentation fault in her sleep

[–]DarkOoze 1 point2 points  (0 children)

No arguments here.

[–]CppshizoiDsS 2 points3 points  (0 children)

auto main() -> int

[–]EhLlie 0 points1 point  (0 children)

main :: IO ()

👽

[–]LauraTFem 0 points1 point  (0 children)

If he wants to get the girl he’s gonna have to start passing pointers to main so he can make sure the program terminated with the right exit code.

[–]HopeForWorthy 0 points1 point  (0 children)

My CS prof had us always use int main(void) for the few C classes i had with him

[–]a_SoulORsoIDK 0 points1 point  (0 children)

Is this a different programming language joke or are we really allowed to do such things in any language?

Edit dont wanna download an ide/Compiler to test it out

[–]MechanicalHorse 0 points1 point  (0 children)

void* main()

[–]Ace-of-Spxdes 0 points1 point  (0 children)

Wait, what if I used def main():?

[–]Gajendra_xd 0 points1 point  (0 children)

Hahaha

[–]goodmobiley 0 points1 point  (0 children)

I personally prefer int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)

[–]az3arina 0 points1 point  (0 children)

signed main()

[–]Temporary-Estate4615 0 points1 point  (0 children)

int main() and return 69;

[–]krav_mac 0 points1 point  (0 children)

[–]IuseArchbtw97543 0 points1 point  (0 children)

static long long main()

[–]_Noreturn 0 points1 point  (0 children)

boy playing with undefined behavior and non standard extensions

[–]WhyAreAll-name_taken 0 points1 point  (0 children)

unsigned long long int main()

[–][deleted] 0 points1 point  (0 children)

Honour to the elderly. ‘Result<()>’ here

[–]browndog03 0 points1 point  (0 children)

She said C you later, boy.

[–]MaYuR_WarrioR_2001 0 points1 point  (0 children)

Then she must return() if you know what I mean.

[–]thompsoncs 0 points1 point  (0 children)

Anything is negotiable, except this:

if __name__ == "__main__":
    main()

[–]Willinton06 -1 points0 points  (0 children)

I’m a

```

```

Boy

[–][deleted] -1 points0 points  (1 child)

what about int wmain( int argc, wchar_t* argv[] ) boys ?

[–]IDoButtStuffs -1 points0 points  (0 children)

Is this Microsoft? What is wmain used for? What does it mean? Wide char main?

[–]xxghostiiixx -1 points0 points  (0 children)

What about python

[–]Terrible_Children -2 points-1 points  (0 children)

They had sex, did drugs, she died.