May 14, 2017
On Wednesday, 10 May 2017 at 12:18:40 UTC, Patrick Schluter wrote:
> On Wednesday, 10 May 2017 at 11:16:57 UTC, Atila Neves wrote:
> [...]
>>
>> The likelihood of a randomly picked C/C++ programmer not even knowing what a profiler is, much less having used one, is extremely high in my experience. I worked with a lot of embedded C programmers with several years of experience who knew nothing but embedded C. We're talking dozens of people here. Not one of them had ever used a profiler.
>
> I've worked 10 years in embedded (industry, time acquisition and network gears) and I can say that there is a good reason to that. It's nearly impossible to profile in an embedded system (nowadays it's often possible because of the generalization of Linux and gnu tools but at that time it wasn't). The tools don't exist or if they do, the instrumentation breaks the constraints of the controller. This was also one of the reason we chose our embedded CPU's very carefully. We always chose processors for which there existed mainstream desktop versions so that we could at least use the confortable tooling to test some parts of the code on a nice environment. We used Z80 (CP/M), 80186 (MS-C on DOS) and then 68030 (Pure-C on Atari TT).
>
> TL;DR profiling for embedded is order of magnitudes harder than for nice OS environments.

IMO it's just different. The thing is, the tools you can use don't need to be marketed as "profilers".
People will always find excuses if they lack time, will or knowledge. In practice, there's always a way to profile and debug, even if you don't have dedicated tools for it. It's also a lot easier to reason about performance on small chips with no caches, ILP, etc. and with fixed instruction timing, than it is on modern complex CPUs with hundreds of tasks competing for resources.
One universal tool is oscilloscope, for sure you have one on your colleague's desk if you really do embedded stuff. A common way to profile on home computers from the '80s such as Atari XE (6502), was simply to change screen colors. That way you always knew the time taken by the measured code with 1-cycle precision. 13.5 scanlines are white? That's 1539 cycles! The time it took to execute a tight loop could even be computed accurately with pen and paper by just looking at the assembly. It's also a lot easier to implement a cycle-exact emulator for such simple chips, and then you can measure everything without observer effect.

May 14, 2017
On 14.05.2017 11:42, Patrick Schluter wrote:
>> ...
>> (a) Trust the programmer.
>> (b) Don't prevent the programmer from doing what needs to be done.
>> (c) Keep the language small and simple.
>> (d) Provide only one way to do an operation.
>> (e) Make it fast, even if it is not guaranteed to be portable.
>> (f) Make support for safety and security demonstrable.
>>
>> Proverb e needs a little explanation. The potential for efficient code
>> generation is one of the most important strengths of C. To help ensure
>> that no code explosion occurs for what appears to be a very simple
>> operation, many operations are defined to be how the target machine's
>> hardware does it rather than by a general abstract rule. An example of
>> this willingness to live with what the machine does can be seen in the
>> rules that govern the widening of char objects for use in expressions:
>> whether the values of char objects widen to signed or unsigned
>> quantities typically depends on which byte operation is more
>> efficient on the target machine.
>>
> If only the gcc and clang designers followed that rule.

It's precisely what they do. You are blaming the wrong people.

> These <beeep>
> consider that undefined behaviour allows to break the code in any way
> they fancy (the nasal demon thing). While pragmaticists interpret it as
> do the thing that is the simplest to implement on that hardware.

Those "pragmaticists" cannot be trusted, therefore they are not programmers. Why do they matter?

> The
> most ridiculous example being the undefined behaviour of signed integer
> overflow. Signed integer overflow is undefined in C because some obscure
> platforms may not use 2 complements for the representation of integers.
> So INT_MAX+1 does not necessarily result in INT_MIN.

It's _undefined_, not implementation-defined or unspecified.

Excerpt from the C standard:
> 3.4.1
> 1 implementation-defined behavior
>   unspecified behavior where each implementation documents how the choice is made
> ...
> 3.4.3
> 1 undefined behavior
>   behavior, upon use of a nonportable or erroneous program construct or of erroneous data,
>   for which this International Standard imposes no requirements
> ...
> 3.4.4
> 1 unspecified behavior
> use of an unspecified value, or other behavior where this International Standard provides
> two or more possibilities and imposes no further requirements on which is chosen in any
> instance
> ...

What is it about "no requirements" that "pragmaticists" fail to understand? Not inventing artificial additional requirements is among the most pragmatic things to do.

> But completely removing the code when one encounters for example:
> if(val+1 == INT_MIN) is simply nuts.

Why? This is simple dead code elimination. The programmer clearly must have known that it is dead code and the compiler trusts the programmer.
The programmer would _never_ break that trust and make a program evaluate INT_MAX+1 !


The corollary to 'trust the programmer' is 'blame the programmer'. Don't use C if you want to blame the compiler.
May 14, 2017
On Sunday, 14 May 2017 at 09:56:18 UTC, Dibyendu Majumdar wrote:
> On Sunday, 14 May 2017 at 02:11:36 UTC, bachmeier wrote:
>> On Sunday, 14 May 2017 at 00:05:56 UTC, Dibyendu Majumdar wrote:
>>
>>> (a) Trust the programmer.
>>
>> I don't understand this point. C doesn't offer the programmer much to work with. If you trust the programmer, shouldn't that mean you provide a large set of tools and let them decide which parts to use? C is pretty much "here are some pointers, go have fun".
>
> Hi - I think this point really is saying that the type system in C is for convenience only - ultimately if you as a programmer want to manipulate memory in a certain way then C assumes you know what you are doing and why. As I said C is really a high level assembler.
>
> Regards

I guess my point is that C only trusts programmers in one direction. You can go as low-level as you want, but it doesn't trust you to use more productive features when that is better (but it certainly gives you the tools to roll your own buggy, hard-to-share version of those features). D, C++, and Rust really do trust the programmer.
May 14, 2017
On Sunday, 14 May 2017 at 09:42:05 UTC, Patrick Schluter wrote:
> But completely removing the code when one encounters for example: if(val+1 == INT_MIN) is simply nuts.

Removing such code is precisely what dmd does: https://issues.dlang.org/show_bug.cgi?id=16268

May 14, 2017
On Sunday, 14 May 2017 at 12:07:40 UTC, Timon Gehr wrote:
> On 14.05.2017 11:42, Patrick Schluter wrote:
>> But completely removing the code when one encounters for example:
>> if(val+1 == INT_MIN) is simply nuts.
>
> Why? This is simple dead code elimination. The programmer clearly must have known that it is dead code and the compiler trusts the programmer.
> The programmer would _never_ break that trust and make a program evaluate INT_MAX+1 !

Well, actually, it makes sense to issue a warning in C.

But in C++ it makes less sense since meta-programming easily can generate such code without breaking the semantics of the program.

> The corollary to 'trust the programmer' is 'blame the programmer'. Don't use C if you want to blame the compiler.

Oh well, there are lots of different checkers for C, so I guess it would be more like "don't blame the compiler, blame the verifier".

May 14, 2017
What does that snippet do ? What should it do?

int caca(void)
{
  for(int i=0xFFFFFFFF; i!=0x80000000; i++)
    printf("coucou");
}
May 14, 2017
On Sunday, 14 May 2017 at 16:44:10 UTC, Patrick Schluter wrote:
> What does that snippet do ? What should it do?
>
> int caca(void)
> {
>   for(int i=0xFFFFFFFF; i!=0x80000000; i++)
>     printf("coucou");
> }

Implicit coercion is a design bug in both C and D... :-P
May 14, 2017
On Sunday, 14 May 2017 at 19:10:05 UTC, Ola Fosheim Grøstad wrote:
> On Sunday, 14 May 2017 at 16:44:10 UTC, Patrick Schluter wrote:
>> What does that snippet do ? What should it do?
>>
>> int caca(void)
>> {
>>   for(int i=0xFFFFFFFF; i!=0x80000000; i++)
>>     printf("coucou");
>> }
>
> Implicit coercion is a design bug in both C and D... :-P

Of course the annoying part is that C allows 2s-complement notation for integer literals, so with warnings on:

int i = 0xFFFFFFFF; // passes without warning.
int i = 0xFFFFFFFFUL; // warning is issued.

May 14, 2017
On Sunday, 14 May 2017 at 10:10:41 UTC, Dibyendu Majumdar wrote:
> In real terms though tools like ASAN and Valgrind if used from the start usually allow you to catch most of the issues. Most likely even better tools for C will come about in time.

See Walter's comment earlier in this thread and my reply.

> I think Rust is a promising language but I don't know enough about it to comment. My impression about Rust is that:
>
> a) Rust has a steep learning curve as a language.

So does C, if you're doing C "correctly".

> b) If you want to do things that C allows you to do, then Rust is no more safer than C.

That's the entire bloody point isn't it? Maybe you shouldn't be doing a lot of the things that C allows you to do.
May 14, 2017
On Sunday, 14 May 2017 at 21:01:40 UTC, Jack Stouffer wrote:
> On Sunday, 14 May 2017 at 10:10:41 UTC, Dibyendu Majumdar wrote:
>> b) If you want to do things that C allows you to do, then Rust is no more safer than C.
>
> That's the entire bloody point isn't it? Maybe you shouldn't be doing a lot of the things that C allows you to do.

Like building a graph?

Sure, Rust is perfect if you can model your world like a tree, but that is usually not what you want if you are looking for performance.

You could replace pointers with integer-ids, but that is just emulating pointers with a construct that may be harder to check for in an automated fashion. So that is not a good solution either.