Naming variables and arguments

I rewatched recently a C++ conference video:

CppCon 2018: Kate Gregory “What Do We Mean When We Say Nothing At All?”

Then I did some research and posted a comment which YouTube decided to remove because it detected “Spam, deceptive practices, & scams policies” violation.It didn’t provide any detail, or a way to check what the comment was or appeal the removal. Nice! I was only able to find out which comment it was by looking at my Your YouTube Comments history and see which comment was NOT there (you have to rely on your memory, because there is no mark that a comment was deleted, or when, on which video…). I will try to reproduce it from memory here (because I cannot find it anywhere), I’ll let the reader decide it it was spam, scam or not:


It’ not enough to name your arguments, the names have to be meaningful.
In 2023 we still have this:

  • const char * strstr ( const char * str1, const char * str2 );
    thanks cplusplus.com ! WTF is str1 and str2? And this is the 1st result on Google (I mean duckduckgo.com)
  • char *strstr(const char *haystack, const char *needle) tutorialspoint.com has it right
  • char *strstr(const char *str,const char *strSearch); so does learn.microsoft.com
  • char *strstr (const char *s1, const char *s2); geeksforgeeks.org can F*** right off
  • char *strstr( const char *str, const char *substr ); cppreference.com does it well
  • char *strstr(const char *string1, const char *string2); IBM can also go to hell
  • char *strstr(const char *s1, const char *s2); so do pubs.opengroup.org

Yay, at least they all name the arguments. Are we happy now?
Well, actually not all, this is what newlib has to say about this:

  • char *_EXFUN(strstr,(const char *, const char *)); 1 or
  • char *strstr (const char *, const char *); 2

Good luck to my fellow embedded developers!

How are junior programmers supposed to name arguments right when this is what they learn from the big guys?

And contrary to what cplusplus.com says, strstr returns a NON const pointer from 2 const pointer. Congratulation!

We are all doomed!

[1] github.com/eblot/newlib/blob/master/newlib/libc/include/string.h
github.com/32bitmicro/newlib-nano-1.0/blob/master/newlib/libc/include/string.h
[2] sourceware.org


… and I understand why YouTYube might detect the “excessive” domain name usage and a couple of links as spam, but FUCK them too for removing my educational comment without providing: 1/ any means to see the comment they have an issue with; 2/ recover a copy; 3/ appeal to restore it… Meanwhile leaving trash comment up and letting actual scams trough!

Why Pascal is better than C

Or to be more specific, why is C bad.

I learnt Pascal before C, and Delphi before C++. So this might be just that. Meaning that my brain is damaged by Pascal 🙂

I’m also Hungarian and the sentence and phrase construction order is different than in English. And because you express your thoughts in language, it pretty much means that we learn to think in different order than humanoids brought up learning English. The order in Hungarian is from big to small. In addresses (country, city, street, number), time (year, month, day, hour, minute, seconds…), names (family name, given name), even in articles (what we want to discuss, and then the details), someone’s stuff rather then stuff of someone.
So this might also contribute to my insanity. What seems to me logical order, might be different for others.

So, Why is C driving me crazy?

There is a lot of reason for it, but for now just look at a simple example.
Lets move some memory around.

When I thing about moving, I think of “Let’s move this to somewhere”. (this, to)
And I would think when a messenger gets a delivery task to carry something, form somewhere, to somewhere that would be the order (form , to).
If I know “where from” then I can already start going that way to pick it up. That is how taxis work, they first only know where to pick up someone. That is also how the IP header is structured (Source IP Address, Destination IP Address).
It feels natural: from somewhere, to somewhere.

So when I want to move some bytes in the memory I would specify from where, to where, and how much.

And that is how Move in Pascal does it:
procedure Move ( const SourcePointer; var DestinationPointer; CopyCount : Integer ) ;

On the other hand memmove in C uses the opposite order.
void * memmove ( void * destination, const void * source, size_t num );
This just doesn’t feel right.

(Both can handle overlapping source, destination buffers, that’s why they are move and not copy.)

When you write in command line you also use source destination order (copy, cp, move, mv) [1]
PHP uses from, to order too. [2]
C#, .NET also uses source, destination order. [3]

You can find the same reversal in source and destination operand ordering in AT&T and Intel assembly formats.
Intel has dest = source order, while AT&T the opposite.
(It’s strange, I’m compelled to end my lines with a semicolon;)

Example: [4]

Intex Syntax AT&T Syntax
mov eax,[ebx]
mov eax,[ebx+3]
add eax, 4
movl (%ebx),%eax
movl 3(%ebx),%eax
addl $4, %eax

I like Intel’s syntax more. Because it resembles the assignment operator order:
eax = *ebx;
eax = *(ebx+3);
eax += 4;

And I know that it is the opposite order (dest, source) of Move, but I’m crazy like that…
But mov actually means: make this equal to that, (there is no actual moving from).

I think the order should always be this, that and here, there.
So if I call a function Move, than it should move from here to there.
But if I call a function MoveTo, then it might move to here from there.
(We could clarify by naming it MoveFrom or MoveFromTo (which sound awful), but the from, to order just seems natural to me.)

Next time I might write something about constructors. Till then you can also read my rant about arrays, and why are they suck in C, and rock in Pascal… 😉

dynamic arrays and the lack of them in C

I love Pascal and Delphi. In particular I love its memory management.
I can use string, array of byte types. They are both dynamic arrays. They are not just pointers to a memory region, they have a size or Length (how Delphi calls them).
The great thing about them is that they can be re-sized. But an other great thing is that you can check their sizes no matter what (if you forgot to remember them, or if you receive them as argument of a function/procedure/method).
SetLength()
Length()
Low()
High()
Open array parameters
^^^^ This is what I need in C!

In C it’s like they want to hide this information from you. First, there is no such thing as dynamic array in C (there are only pointers). There are arrays in C++ (but I read that you should avoid them at all cost, and use vector instead), but also you cannot re-size them, so they are not fixed length, but not really dynamic either.
So how can you get the length of an array or memory region?
common methods:
In C you can use #define lengthof(array) (sizeof(array)/sizeof(array[0])) if it’s a fixed length array, but you cannot use it on function arguments, or pointers…

There is a clever template (if you write it) in C++
template
inline unsigned int length( T(&a)[N] ) { return N; }
that can be used to determine length of arrays.

So where are the real dynamic, realizable arrays, and how to implement them?
If you want to allocate memory run-time (and re-size them) you can use malloc() (realloc() and free())
That’s all fine until you want to get the size of them. Which can happen if you allocate the memory outside of a function where you want to use it. There is no std libc function to get the (malloc) allocated memory size which is kept somewhere (so free() can free it, realloc can re-size it and available memory regions can be kept track of). There is however a GNU extension malloc_usable_size() which I, we desperately need (even if we didn’t know it).
.. Well we need an array whose size we can check no matter if it’s dynamic or static, but…
Also note that malloc_usable_size does NOT actually return the requested size, but the allocated one (due to alignment, minimum block size), but at least we can use it for asserts.
So we still need to keep track of array sizes separately (extra variables, extra arguments) and risk messing them up…
(or rewrite everything to use structures of size, pointer pairs)

Another topic is multidimensional (dynamic) arrays (not just arrays of arrays)…

Note: This actually I have written just now 🙂 See I do not just reuse ages old materials:)

Why Delphi / pascal is better than C++

Ok, there are characteristics where c++ has the advantage, but I’m not talking about that now.

Delphi has properties! They are great if you are in the process of creating a new library. Why? Because when you start you can just set a bunch of variables public, you do not need to implement setter and getter functions. Later you can decide to make some of those variables private, and create properties and setter functions for them (checking, limiting range, do stuff on change). Usually you do not need to write getter functions at all.

private
FPosStart,FPosEnd:integer; /// ...
protected
procedure SetPosStart(value:integer); /// ...
published
property PosStart:integer read FPosStart write SetPosStart;

The main advantage here is not that we do not have to write getter function.
Imagine that the library is used extensively (by you, or others). AFAIK in C++ a change like this would break compatibility. Code would have to be changed to PosStart() / getPosStart() and setPosStart(…) form ‘… PosStart’ and ‘PosStart = …’

In Delphi constructors are inherited. It’s not a big deal, I did not even realize it until now. I’m reading Large Scale C++ Software Design about cyclic dependencies, levelization, mutually dependant components. It suggests not to write constructors that convert between classes, but rather write separate converter class with static methodes. But that does not seem very objectum oriented to me. It reminds me of itoa() and stuff like that. It works but still… So, I was wondering why not create descendant classes (or ancestor classes) and implement an additional constructor in the descendant class, that converts form the ancestor classes. It’s a little more typing but not much… or so I thought, then I realized that I needed to reimplement all the ancestors constructors… which is not the case in delphi. It’s a rather common practice to use your own descendant classes of standard controls from the start, just in case you will ever need to add some functionality. It’s easy, and cheap.
TMyCollection = class(TCollection) end;