Jump to page: 1 2
Thread overview
Compile time vs run time -- what is the difference?
Dec 28, 2022
thebluepandabear
Dec 28, 2022
Mike Parker
Dec 28, 2022
thebluepandabear
Dec 28, 2022
Ali Çehreli
Dec 28, 2022
Ali Çehreli
Jan 01, 2023
H. S. Teoh
Jan 01, 2023
Ali Çehreli
Jan 01, 2023
Salih Dincer
Jan 01, 2023
H. S. Teoh
December 28, 2022

I am reading through the free book on learning D by Ali Çehreli and I am having difficulties understanding the difference between compile time execution and run time execution in D language.

What I do understand is that compile time and run time are the two processes that your code goes through to be executed natively. Compile time is the first stage. During compile time, the compiler checks for basic syntax errors such as a missing semicolon, typos throughout the codebase. Then the run time stage begins. Other errors are only able to be spotted during run time such as exceptions, dividing by zero, assert blocks.

In Java and some other languages, during compile time the code gets executed into Java bytecode. This also happens for C#. I don't know if there is an equivalent 'intermediate' language for D that your code gets translated to.

In general, I have a very vague understanding of these concept.s I don't understand the basics of how compile time and run time works in D language, it wasn't really explained in the book so when I see terms like 'compile time' and 'run time' I only have a very vague idea of what these things mean and how the process works for D language when compared to other high level languages.

Any help would be appreciated.

December 27, 2022

On 12/27/22 9:31 PM, thebluepandabear wrote:

>

I am reading through the free book on learning D by Ali Çehreli and I am having difficulties understanding the difference between compile time execution and run time execution in D language.

Compile time execution is running your code being compiled while being compiled. It allows you to generate compile-time data without having to write specialized "compile time only" constructs like templates or explicitly marked functions (as other languages typically do).

Compile time data doesn't consume any runtime to execute, it's already done by the time your binary is running. It also is usable at compile time, for things like static if, or mixin.

The intermediate language being executed is the parsed and semantically analyzed AST nodes.

-Steve

December 28, 2022

On Wednesday, 28 December 2022 at 02:31:45 UTC, thebluepandabear wrote:

>

In Java and some other languages, during compile time the code gets executed into Java bytecode. This also happens for C#. I don't know if there is an equivalent 'intermediate' language for D that your code gets translated to.

With statically compiled languages like D, C, and C++, the compiler ultimately translates your source code to what's referred to as "machine code". Compilers output object files, which are in turn linked into an executable file by a linker.

Static compilers can use intermediate representations like Java bytecode. For example, compilation could consist of two steps handled by two different programs, one that translates the source to bytecode, and one that translates the bytecode to an object file.

This is how LLVM-based compilers like Clang and LDC work. Clang translates C source to LLVM IR (Intermediate Representation). LDC translated C source to LLVM IR. Both pass the generated IR to the LLVM compiler, which outputs the object files that are then given to a linker. Static Java compilers do the same thing with Java bytecode. Java JIT compilers built into Java VMs translate Java bytecode to machine code while the program is running.

So compilation is just the act of translating from one source format to another (e.g., raw source code to machine code, or raw source code to bytecode, or bytecode to machine code).

>

In general, I have a very vague understanding of these concept.s I don't understand the basics of how compile time and run time works in D language, it wasn't really explained in the book so when I see terms like 'compile time' and 'run time' I only have a very vague idea of what these things mean and how the process works for D language when compared to other high level languages.

Anything that happens at compile time means it happens while the compiler is translating the source. Anything that happens at run time happens while the compiled program is running.

So take this example:

uint fourcc(char a, char b, char c, char d)
{
    return (a << 0) | (b << 8) | (c << 16) | (d << 24);
}

// Here, fourcc is evaluated at compile time
enum nv12 = fourcc('N', 'V', '1', '2');

void main()
{
    writeln(nv12);

    // Here, fourcc is evaluated at runtime
    writeln(fourcc('Y', 'V', '1', '2'));
}

When the compiler is processing this source code, it encounters the declaration of nv12. Since this is an enum, it's a compile-time constant that cannot be changed at run time. That means that any value used to initialize it must also be known at compile time. One way to do that would be to use a literal, but in this case it's initialized with a call to the fourcc function. So the compiler evaluates the fourcc function and uses the result as the initializer of nv12.

In other words, the end result is just the same as if I had written enum nv12 = 842094158.

The second call to fourcc in the main function is not in a compile-time context, so it does not happen at compile time. It happens at run time, i.e., when you double click the executable that the compiler and linker generated (or type its name on the command line).

The general rule is: if a function call is in a context such that it must be evaluated at compile time, then the compiler will evaluate it. Otherwise, it's a normal run-time evaluation.

December 28, 2022
On Wednesday, 28 December 2022 at 02:31:45 UTC, thebluepandabear wrote:
>
> ..
> Other errors are only able to be spotted during run time such as exceptions, dividing by zero, assert blocks.

With regards to the 'assert blocks' you mention, D (like C++) has both static assert and runtime assert.

// ---
module test;
@safe:

import std;

void main()
{
  string val = "some string";
  static assert(is(typeof(x) : int)); // assertion fails at compile time.
  assert(val == "some other string"); // assertion fails at runtime.
}
// ---
December 28, 2022
On Wednesday, 28 December 2022 at 09:10:38 UTC, areYouSureAboutThat wrote:
> On Wednesday, 28 December 2022 at 02:31:45 UTC, thebluepandabear wrote:
>>
>> ..
>> Other errors are only able to be spotted during run time such as exceptions, dividing by zero, assert blocks.
>
> With regards to the 'assert blocks' you mention, D (like C++) has both static assert and runtime assert.
>
> // ---
> module test;
> @safe:
>
> import std;
>
> void main()
> {
>   string val = "some string";
>   static assert(is(typeof(x) : int)); // assertion fails at compile time.
>   assert(val == "some other string"); // assertion fails at runtime.
> }
> // ---

Before even running the code I get an IDE warning (IntelliJ). Does IntelliJ compile the code in the background?
December 28, 2022
On 12/27/22 18:31, thebluepandabear wrote:

> What I do understand is that compile time and run time are the two
> processes that your code goes through to be executed natively.

There is a confusion: Compile time ends when the compiler generates the executable program, one that will be executed natively.

Run time is each time when the user starts the executable program by typing its name followed by the Enter key, double clicking on it, etc.

For a program that was extremely simple, bug-free, lucky, etc. there may be as few as a single compilation and infinite number of executions (run times).

On the other hand, for a program that could never be compiled successfully, there may be infinite number of compilations and zero run times.

> In Java and some other languages, during compile time the code gets
> executed into Java bytecode. This also happens for C#. I don't know if
> there is an equivalent 'intermediate' language for D that your code gets
> translated to.

No, D does not use that model.

Copying a comment of yours:

> Before even running the code I get an IDE warning
> (IntelliJ). Does IntelliJ compile the code in the background?

Yes, many IDEs continuously compile the code as you type the source code to understand it to give you such help. I don't think any of them can run the program though because the program can be in a state that could harm its environment like deleting unwanted files.

Ali

December 28, 2022
On 12/28/22 08:04, Ali Çehreli wrote:

> I don't think any of them can run the program though because
> the program can be in a state that could harm its environment
> like deleting unwanted files.

I was too eager there. Likely no IDE goes that far. All they need is to understand the code enough to give help. They must stop at some point in the following steps of compilation:

- preprocessing (does not exist for D)

- lexical analysis

- parsing

- semantic analysis

I copied those items from Wikipedia:

  https://en.wikipedia.org/wiki/Compiler

It lists the later stages of compilation as

- intermediate representation

- code optimization

- code generation

Ali

December 28, 2022
On Wednesday, 28 December 2022 at 12:42:24 UTC, thebluepandabear wrote:
>
> Before even running the code I get an IDE warning (IntelliJ). Does IntelliJ compile the code in the background?

It will NOT compile successfully unless you do one of these things:

(1) ensure the result of the 'static assert' is true.
(2) comment out the static assert.

Once you do either of (1) or (2) above, it will compile to an executable format.

When you execute it, the runtime will catch the 'assert' failure (ie. assertion == false), and the runtime will bring your program to an immediate halt.

This was just meant to be an example of differentiating compile time from runtime, as per you question.

With static assert, your logic testing is traversed during compilation, and your compilation will come to a stop when the assertion is found to be false, whereas your asserts are traversed during program execution, and if they are found to be false, your program comes to a stop.

https://dlang.org/spec/version.html#static-assert
https://tour.dlang.org/tour/en/gems/contract-programming


December 31, 2022
On Wed, Dec 28, 2022 at 02:31:45AM +0000, thebluepandabear via Digitalmars-d-learn wrote:
> I am reading through the free book on learning D by Ali Çehreli and I am having difficulties understanding the difference between compile time execution and run time execution in D language.

It's very simple: in a compiled language like D, your program goes through 3 stages:

1) Source code: the human-readable text that you write.

2) Compilation: this is when the compiler is compiling your program.
   IOW, "compile time". Compile time happens once when you compile your
   program.

3) Binary executable: the result of compilation.  When you run this
   executable, that's "runtime".  Runtime happens every time you run the
   program.


Stage (2) is transient, and only happens inside the compiler. It can be broken down into several steps:

a) Lexing & parsing: the compiler reads the source code, breaks it into
   tokens (keywords, identifiers, operators, etc.), and constructs from
   them an abstract syntax tree (AST) that represents your program. Here
   is where typos and syntax errors are detected.

b) Semantic analysis: the compiler processes the AST and assigns meaning
   to each corresponding programming construct. Here is where (some)
   logic errors are detected (reference to an undefined identifier,
   invalid operations on a data type, calling a function with the wrong
   number of arguments, etc.).

c) Code generation: based on the semantics the compiler assigned to your
   program, it emits a series of CPU instructions that implement these
   semantics.  These instructions are generally saved into either
   intermediate object files that must later be linked together, or
   directly into the final executable.


D's compile-time capabilities are mainly of two categories:

i) AST manipulation: templates, static if, static foreach, and
   pragma(msg) belong to this category. This generally happens between
   steps (a) and (b).

ii) CTFE (compile-time function evaluation): this happens somewhere
   around step (c), and mainly consists of the compiler interpreting
   part of the program using an internal interpreter in order to compute
   the value of a function at compile-time.  This is triggered when this
   value is required in order to resolve something that's needed during
   compilation.

For more details, see:

	https://wiki.dlang.org/Compile-time_vs._compile-time


T

-- 
If you think you are too small to make a difference, try sleeping in a closed room with a mosquito. -- Jan van Steenbergen
December 31, 2022
On 12/31/22 16:42, H. S. Teoh wrote:

> "runtime"

Going off topic, I've settled on three different spelling of that (those? :) ):

- run time: As in this topic, things can happen at run time.

- run-time: Adjective, as in run-time value of something.

- runtime: The D runtime.

Ali

« First   ‹ Prev
1 2