www.digitalmars.com         C & C++   DMDScript  

digitalmars.dip.ideas - No main() Error

reply Ron Tarrant <rontarrant gmail.com> writes:
I'd like to suggest that an error condition be added wherein, if 
there is no main() function, the compiler will treat this as a 
fundamental error and report it upon exit.

Most of the code I write these days is in Python. I turned to D 
for a small project this morning and while doing some preliminary 
exploration into file handling, I got a "Declaration expected" 
error while trying to write a foreach() loop.

What it turned out to be is that I'd forgotten to wrap my code in 
a main() function. Dumb mistake, not the kind of mistake most 
would make. I'm too used to writing in Python, I guess.

I expect most people reading this will think this is so 
fundamental as to not be needed, but I'm hoping to avoid, in 
future, going around in circles for an hour and a half while 
trying to do something so trivial.

Thank you for your kind consideration of this matter.
Feb 02
next sibling parent reply "Richard (Rikki) Andrew Cattermole" <richard cattermole.co.nz> writes:
Due to separate compilation, the D compiler cannot know if a start 
address exists with a function provided for it.

The responsibility of this is the linker, which will error if no start 
address with executable code is provided.
Feb 02
parent reply Ron Tarrant <rontarrant gmail.com> writes:
On Sunday, 2 February 2025 at 10:14:15 UTC, Richard (Rikki) 
Andrew Cattermole wrote:
 Due to separate compilation, the D compiler cannot know if a 
 start address exists with a function provided for it.

 The responsibility of this is the linker, which will error if 
 no start address with executable code is provided.
I guess I'm not being very clear. I'll try again... On the first pass, I'd like to suggest that the compiler could check for an occurrence of "main" followed by "(" and spit out an error if it's not found. Any of the following would avoid the error: ``` void main( <returned type> main ( void main ( ``` And other variations thereof.
Feb 04
parent reply "Richard (Rikki) Andrew Cattermole" <richard cattermole.co.nz> writes:
On 04/02/2025 10:16 PM, Ron Tarrant wrote:
 On Sunday, 2 February 2025 at 10:14:15 UTC, Richard (Rikki) Andrew 
 Cattermole wrote:
 Due to separate compilation, the D compiler cannot know if a start 
 address exists with a function provided for it.

 The responsibility of this is the linker, which will error if no start 
 address with executable code is provided.
I guess I'm not being very clear. I'll try again... On the first pass, I'd like to suggest that the compiler could check for an occurrence of "main" followed by "(" and spit out an error if it's not found. Any of the following would avoid the error: ``` void main( <returned type> main ( void mainĀ  ( ``` And other variations thereof.
What do you mean by first pass? The reasons for this to not work is because the compiler cannot do it, only the linker has the information needed to emit an error. Syntax does not play a role in this.
Feb 04
parent reply "Richard (Rikki) Andrew Cattermole" <richard cattermole.co.nz> writes:
On 04/02/2025 10:20 PM, Richard (Rikki) Andrew Cattermole wrote:
 Syntax does not play a role in this.
I should clarify this, the compiler already has functions for checking if a function is a main function. https://github.com/dlang/dmd/blob/89b93e8b0952e8bf5dd73020a23cd7cb1897adcb/compiler/src/dmd/func.d#L595 It looks like it can work without semantic analysis having been done too.
Feb 04
next sibling parent reply Ron Tarrant <rontarrant gmail.com> writes:
On Tuesday, 4 February 2025 at 09:25:14 UTC, Richard (Rikki) 
Andrew Cattermole wrote:
 On 04/02/2025 10:20 PM, Richard (Rikki) Andrew Cattermole wrote:
 Syntax does not play a role in this.
I should clarify this, the compiler already has functions for checking if a function is a main function. https://github.com/dlang/dmd/blob/89b93e8b0952e8bf5dd73020a23cd7cb1897adcb/compiler/src/dmd/func.d#L595 It looks like it can work without semantic analysis having been done too.
Thanks for the clarification. I confess I know nothing about compiler/linker design. Is it possible for the compiler, having read the code file, to pass along enough information to the linker so it knows that a) there is no `main()` function in the code file and b) the current build isn't a library, thus making it possible for the linker to inform the user in clearer language that something's off?
Feb 04
next sibling parent monkyyy <crazymonkyyy gmail.com> writes:
On Tuesday, 4 February 2025 at 19:41:09 UTC, Ron Tarrant wrote:
 On Tuesday, 4 February 2025 at 09:25:14 UTC, Richard (Rikki) 
 Andrew Cattermole wrote:
 On 04/02/2025 10:20 PM, Richard (Rikki) Andrew Cattermole 
 wrote:
 Syntax does not play a role in this.
I should clarify this, the compiler already has functions for checking if a function is a main function. https://github.com/dlang/dmd/blob/89b93e8b0952e8bf5dd73020a23cd7cb1897adcb/compiler/src/dmd/func.d#L595 It looks like it can work without semantic analysis having been done too.
Thanks for the clarification. I confess I know nothing about compiler/linker design. Is it possible for the compiler, having read the code file, to pass along enough information to the linker so it knows that a) there is no `main()` function in the code file and b) the current build isn't a library, thus making it possible for the linker to inform the user in clearer language that something's off?
changing the c abi isnt really on the table without replacing entire os's youd be better off writing a "rdmd" clone that attempts to run the file if it gets the error places and top level statements in a main function
Feb 04
prev sibling parent reply "Richard (Rikki) Andrew Cattermole" <richard cattermole.co.nz> writes:
On 05/02/2025 8:41 AM, Ron Tarrant wrote:
 On Tuesday, 4 February 2025 at 09:25:14 UTC, Richard (Rikki) Andrew 
 Cattermole wrote:
 On 04/02/2025 10:20 PM, Richard (Rikki) Andrew Cattermole wrote:
 Syntax does not play a role in this.
I should clarify this, the compiler already has functions for checking if a function is a main function. https://github.com/dlang/dmd/ blob/89b93e8b0952e8bf5dd73020a23cd7cb1897adcb/compiler/src/dmd/ func.d#L595 It looks like it can work without semantic analysis having been done too.
Thanks for the clarification. I confess I know nothing about compiler/linker design. Is it possible for the compiler, having read the code file, to pass along enough information to the linker so it knows that a) there is no `main()` function in the code file and b) the current build isn't a library, thus making it possible for the linker to inform the user in clearer language that something's off?
The compiler doesn't need to do anything extra. All linkers can and will error if the start address / main function is missing. What you are asking for is a nice customized error message for D. Which as far as I'm aware is not supported by any linker.
Feb 04
parent reply Ron Tarrant <rontarrant gmail.com> writes:
On Wednesday, 5 February 2025 at 05:34:09 UTC, Richard (Rikki) 
Andrew Cattermole wrote:
 What you are asking for is a nice customized error message for 
 D.

 Which as far as I'm aware is not supported by any linker.
So, what you're saying is that DMD doesn't have its own linker? That never occurred to me. On the other hand, if D uses a linker previously built for other compilers (C or C++, I assume) I'm surprised that this already-existing linker doesn't have such an error message. On the other-other hand, if linkers are used for building both executables and libraries, it does make sense in a way. I mean, otherwise the linker developer would have to allow for a command line switch telling the linker the specific output of the build: library, or executable. But this now sounds like a discussion for another venue. Not sure which, so instead, I'm going to write up a little note to post on my monitor bezel, something like: Does your code have a main() function? I guess that will have to do. Thanks for the discussion, guys. It's been fun.
Feb 05
parent "Richard (Rikki) Andrew Cattermole" <richard cattermole.co.nz> writes:
On 05/02/2025 9:48 PM, Ron Tarrant wrote:
 On Wednesday, 5 February 2025 at 05:34:09 UTC, Richard (Rikki) Andrew 
 Cattermole wrote:
 What you are asking for is a nice customized error message for D.

 Which as far as I'm aware is not supported by any linker.
So, what you're saying is that DMD doesn't have its own linker? That never occurred to me.
Not anymore. We did have Optlink for Windows 32bit, but that was written in the 80's for C/C++.
 On the other hand, if D uses a linker previously built for other 
 compilers (C or C++, I assume) I'm surprised that this already-existing 
 linker doesn't have such an error message.
It does, when you produce an executable. All of them have had it since their inception (more or less).
 On the other-other hand, if linkers are used for building both 
 executables and libraries, it does make sense in a way. I mean, 
 otherwise the linker developer would have to allow for a command line 
 switch telling the linker the specific output of the build: library, or 
 executable.
You specify if you want a shared library or executable. Some will also act as an archiver for static libraries.
Feb 05
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 2/4/2025 1:25 AM, Richard (Rikki) Andrew Cattermole wrote:
 It looks like it can work without semantic analysis having been done too.
Linkage requires semantic analysis. isNested and isMember are not determined by the parser, either.
Feb 12
parent "Richard (Rikki) Andrew Cattermole" <richard cattermole.co.nz> writes:
On 13/02/2025 10:13 AM, Walter Bright wrote:
 On 2/4/2025 1:25 AM, Richard (Rikki) Andrew Cattermole wrote:
 It looks like it can work without semantic analysis having been done too.
Linkage requires semantic analysis. isNested and isMember are not determined by the parser, either.
Yeah I learned that two days ago. That it was much later than I thought it would be. Regardless it doesn't change my responses here regarding main function detection. It doesn't nor should it be special cased like originally requested as that is the job of the linker.
Feb 12
prev sibling next sibling parent reply Paul Backus <snarwin gmail.com> writes:
On Sunday, 2 February 2025 at 10:06:29 UTC, Ron Tarrant wrote:
 Most of the code I write these days is in Python. I turned to D 
 for a small project this morning and while doing some 
 preliminary exploration into file handling, I got a 
 "Declaration expected" error while trying to write a foreach() 
 loop.
It sounds like what you are really asking for here is a better error message when the compiler encounters a statement outside of a function. E.g., if the compiler sees a control-flow keyword like `foreach` or `if` at the top-level scope of a module, instead of saying "declaration expected", it could say something like "`foreach` statement is not allowed outside of a function." I agree that this would be a worthwhile improvement.
Feb 04
next sibling parent Ron Tarrant <rontarrant gmail.com> writes:
On Tuesday, 4 February 2025 at 22:14:40 UTC, Paul Backus wrote:

 It sounds like what you are really asking for here is a better 
 error message when the compiler encounters a statement outside 
 of a function.

 E.g., if the compiler sees a control-flow keyword like 
 `foreach` or `if` at the top-level scope of a module, instead 
 of saying "declaration expected", it could say something like 
 "`foreach` statement is not allowed outside of a function."

 I agree that this would be a worthwhile improvement.
Yes, well put. And thanks for the support.
Feb 05
prev sibling parent Atila Neves <atila.neves gmail.com> writes:
On Tuesday, 4 February 2025 at 22:14:40 UTC, Paul Backus wrote:
 On Sunday, 2 February 2025 at 10:06:29 UTC, Ron Tarrant wrote:
 Most of the code I write these days is in Python. I turned to 
 D for a small project this morning and while doing some 
 preliminary exploration into file handling, I got a 
 "Declaration expected" error while trying to write a foreach() 
 loop.
It sounds like what you are really asking for here is a better error message when the compiler encounters a statement outside of a function. E.g., if the compiler sees a control-flow keyword like `foreach` or `if` at the top-level scope of a module, instead of saying "declaration expected", it could say something like "`foreach` statement is not allowed outside of a function." I agree that this would be a worthwhile improvement.
This makes sense to me.
Feb 12
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
I'm not sure what code you're writing. Can you post an example, please?
Feb 12
next sibling parent reply monkyyy <crazymonkyyy gmail.com> writes:
On Wednesday, 12 February 2025 at 18:57:28 UTC, Walter Bright 
wrote:
 I'm not sure what code you're writing. Can you post an example, 
 please?
```d import std; "hello world".writeln; ```
Feb 12
parent Walter Bright <newshound2 digitalmars.com> writes:
thank you
Feb 13
prev sibling parent Ron Tarrant <rontarrant gmail.com> writes:
On Wednesday, 12 February 2025 at 18:57:28 UTC, Walter Bright 
wrote:
 I'm not sure what code you're writing. Can you post an example, 
 please?
Hi, Walter. Thanks for replying. Although the errors may not be the same (I don't remember what errors I got, frankly. I've put the entire experience out of my mind since it was a tad embarrassing and I've long since tossed the code.) it was something like this: ``` module copy_file_std; import std.stdio; import std.file; import std.exception; // this is a new comment void copyFile(string sourcePath, string destinationPath) { try { // Option 1: Using std.file.copy (Simplest for basic copies) copy(sourcePath, destinationPath); writeln("File copied successfully using std.file.copy."); } catch (Exception e) { stderr.writeln("Error copying file: ", e.msg); } } string source = "./copy_file_std.d"; string destination = "./subdir/copy_file_std.d"; if (!exists(source)) { stderr.writeln("Source file does not exist!"); return; } copyFile(source, destination); ``` I neglected to wrap the last statement in ```void main() {}``` which, naturally, fixed it.
Feb 15