August 01, 2014
Am Fri, 01 Aug 2014 07:01:48 +0000
schrieb "Jonathan M Davis" <jmdavisProg@gmx.com>:

> Since all template instantiations must happen when you compile your program rather than in any libraries you're linking against, why would it matter? If you compile your program without

That's not true, template instances emit weak symbols. If you link against a compiled library which also has instantiated the same templates this library provides the same weak symbols. Which symbols are actually used in the final executable is up to the linker and not standardized.
August 01, 2014
Am 01.08.2014 12:03, schrieb "Marc Schütz" <schuetzm@gmx.net>":
>
> A compiler is a program that turns code in one programming language to
> equivalent machine code, according to a language specification. There
> are obviously many different equivalent machine code programs
> corresponding to any sufficiently complex higher-level program.
> Classifying them into optimized and unoptimized ones is rather
> arbitrary. The same goes for safe vs. unsafe optimizations.
>
> To achieve what you want, the compiler would have to ignore the actual
> language specification and use a different one that is tweaked according
> to your criteria. I don't think this is desirable. If the official
> language specification has parts that can lead to the errors you want to
> avoid, then it's not the compiler's fault, and therefore the compiler
> should not be changed to workaround it. Instead, deficiencies in the
> specification should be fixed there.

I'd prefer language specifications *not* to include such parts.
C wouldn't be any worse without the "you can eliminate writes to code that's not read afterwards" part, for example.

So I wish D could resist adding such "dangerous"/unexpected things to the standard and only allow such optimizations in an "unsafe" optimization mode.

Cheers,
Daniel
August 01, 2014
On Thursday, 31 July 2014 at 21:11:17 UTC, Walter Bright wrote:
> On 7/31/2014 1:52 PM, Sean Kelly wrote:
>> Could you expand on what you consider input?
>
> All state processed by the program that comes from outside the program. That would include:
>
> 1. user input
> 2. the file system
> 3. uninitialized memory
> 4. interprocess shared memory
> 5. anything received from system APIs, device drivers, and DLLs that are not part of the program
> 6. resource availability and exhaustion
>
>
>> For example, if a
>> function has an "in" contract that validates input parameters, is
>> the determination that a parameter is invalid a program bug or
>> simply invalid input?
>
> An "in" contract failure is a program bug. Contracts are ASSERTIONS ABOUT THE CORRECTNESS OF THE PROGRAM LOGIC. They are not assertions about the program's input.
>
>> If you consider this invalid input that
>> should be checked by enforce(), can you explain why?
>
> This says it better than I can:
>
> http://en.wikipedia.org/wiki/Design_by_contract

ok, can this be considered a good summary of using assertions/contracts for services where risk of entering undefined state is unacceptable?

1) never use `assert` or contracts in actual application code, use `enforce` instead
2) never use `enforce` in library code unless it does actual I/O, use contracts instead
3) always distribute both release and debug builds of libraries and always run tests in both debug and release mode

Does it make sense? Your actual recommendation contradict each other but it is best what I was able to combine them into.
August 01, 2014
"Johannes Pfau"  wrote in message news:lrfqqt$1jem$1@digitalmars.com...

> Which symbols are
> actually used in the final executable is up to the linker and not
> standardized.

Isn't it?  dmd will set it up so the definitions in the library will only get pulled in if undefined, and this will usually mean any definitions in the main object files will override the library ones.  It should work this way on all platforms.

Of course, definitions in different object files will be subject to comdat folding and that is not standardized. 

August 01, 2014
"Daniel Gibson"  wrote in message news:lrg0k5$1nl1$1@digitalmars.com...

> I'd prefer language specifications *not* to include such parts.
> C wouldn't be any worse without the "you can eliminate writes to code that's not read afterwards" part, for example.

Of course it would, that's why that's in there!!!

int *x = 0; // initialize just to be safe
...
x = ...;

You've just wasted a write.  Your program is now slower than it needs to be.

struct MyStruct s;
mystruct_init(&s);
s->field = something;
s->otherfield = somethingElse();

mystruct_init has to initialize all fields of s (to keep programmer suicide rates down) and yet you've just written over some of the values!  The compiler can clearly see that you never read from field and otherfield between the first write and the second. 

August 01, 2014
On Friday, 1 August 2014 at 01:41:40 UTC, Daniel Gibson wrote:
>
> Yep, also a good point.
> (Actually it's 187 -f* options, the rest is -O* which can't be combined of course and some of them most probably imply many of the -f* switches, but it'll still be an unmanageable/untestable amount of possible configurations)
>
Actually, it's much worse than that. ;)  All of the -O switches in GCC have a set of -f switches that they enable or disable.  What they DON'T tell you up front is that set of switches also enables other optimisations. [0]  I encountered a situation a couple months ago where this actually mattered (i.e. runtime segfault) for one particular C file if you built it with levels above -O0, but enabling every single -f switch worked fine (still not sure why; solved by switching to Clang and it compiles and runs at all -O levels with no warnings).

-Wyatt

[0] https://gcc.gnu.org/wiki/FAQ#Is_-O1_.28-O2.2C-O3_or_-Os.29_equivalent_to_individual_-foptimization_options.3F
August 01, 2014
On Friday, 1 August 2014 at 08:21:28 UTC, Kagamin wrote:
> On Thursday, 31 July 2014 at 21:29:59 UTC, Sean Kelly wrote:
>> So effectively, any factor occurring at runtime.  If I create a
>> library, it is acceptable to validate function parameters using
>> assert() because the user of that library knows what the library
>> expects and should write their code accordingly.  That's fair.
>
> He should, but what if he doesn't and the library is phobos or druntime (which are compiled in release mode)? BTW, druntime can't use enforce and doesn't verify its input.

Druntime uses contracts and asserts in places. Which are of course removed because we ship only a "release" build.  Once again, the worst naming for a compiler switch ever. What I really want is a way to ship release and non-release builds (ie. checked and unchecked) and have the proper one chosen at link time based on build flags. Basically toss the -defaultlib and -debuglib and replace it with -checkedlib and -uncheckedlib.
August 01, 2014
On Friday, 1 August 2014 at 14:10:14 UTC, Sean Kelly wrote:
> Druntime uses contracts and asserts in places. Which are of course removed because we ship only a "release" build.  Once again, the worst naming for a compiler switch ever. What I really want is a way to ship release and non-release builds (ie. checked and unchecked) and have the proper one chosen at link time based on build flags. Basically toss the -defaultlib and -debuglib and replace it with -checkedlib and -uncheckedlib.

As a consequence of this thread I think I am going to change the way DMD is packaged on Arch Linux to at least use -debuglib :) Right we don't provide even that...
August 01, 2014
On Friday, 1 August 2014 at 07:01:49 UTC, Jonathan M Davis wrote:
> Since all template instantiations must happen when you compile your program rather than in any libraries you're linking against, why would it matter?

AFAIK, there's no distinction between a library and a program in D, only modules and packages. How would it differentiate them? And I didn't see any documented guarantee for template instantiation optimization behavior.

> The compiler would never try to share any template instantiations across them. They wouldn't even be involved with each other until the linker was run on them, so the compiler wouldn't even have the chance to try and share anything between them.

Nobody cares about intermediate files, only what gets into the final executable matters, and that is decided by the linker, and it will remove redundant template instances.
August 01, 2014
On 8/1/14, 12:40 AM, David Bregman wrote:
> It's not a "position". I'm just giving you the definition of assume so
> you can understand the difference from assert.

After reading your posts I still can't understand what your definition of "assume" is. Here's what I found:

> assert:
> is a runtime check of the condition.
> is a debugging/correctness checking feature.
> is used when the expression is believed true, but is not proven so.
> (if it was proven, then there is no purpose in asserting it with a redundant runtime check that is guaranteed to never activate.)
>
> assume:
> passes a hint to the optimizer to allow better code generation.
> is used when the expression is proven to be true (by the programmer, like @trusted).

There are a few corrections needed for "assert", i.e. "is a runtime check of the condition in debug mode". The whole "believed true but not proven so" is... odd, seeing as assert takes expressions that are considered tautological within the design, and sometimes provable automatically (e.g. after inlining).

Anyhow, if "assume" is to be taken at face value the its semantics has always been what Walter intended for "assert". (Again "proven to be true" is an eyebrow raiser because when one thinks of "proof" of semantics of programs one thinks of state analysis or progress and preservation and such.)

You may dislike what Walter wanted assert to be, but really this has been it from the beginning. Back in the day when I joined him I questioned the validity of making "assert" a keyword. He explained that he wanted it to be magic in the same way he discusses in this thread.


Andrei