What are Zero Cost Abstractions?It is the ability to create an abstraction, to have a greater expressivity than you are doing, without incurring in cost because of this.In general when you create an abstraction and hide an implementation detail often use some mechanism that imposes some memory or processing cost that is not always noticeable, but if you measure it is there, and accumulating with others in large quantity can make the application be perceptively less efficient.It is a noble goal and I like it, but it is rare to achieve effective result.Origin of the termIt is very rare a language to achieve many good abstractions at no cost. What is done is this cost to be reduced, or to be obvious, or to pay only if to use ease, but to have a way to do, even more complex, without cost.What you don’t use, you don’t pay for. And further: What you do use, you couldn’t hand code any better.--Bjarne StroustrupThe first sentence of the quote gives a lot of room for much to be accepted as ZCA. The second shows the hardest side to get.The term began to be used more strongly by C++ (given to perceive by the quote above the creator of the language), including is part of his philosophy. And marketing. I am not saying that C++ is not efficient and often does not reach the goal of zero cost abstraction, but she reaches less times than it makes it look. There are even articles and lectures on the subject, not everything is so cost-free, even comparing only with C.There are several C++ mechanisms that impose cost and when they launch it they say it is cost-free. In general it is very efficient, but at no cost it is usually exaggerated.For example C, it has many features that we can say that are zero-cost abstractions, this is given whenever that code produces an exactly equal Assembly you would if you had to write it in hand and with the ability to do as optimized as possible. If you can't, if you put an extra instruction, if you need to occupy some extra space, if you have to opt for an instruction that costs more expensive, if the required order is one that does not privilege processor optimizations at the time of execution, then the abstraction cost was not zero.I have seen definition that says the meaning would be:costs are well defined, predictable and more or less controllableThat's a fallacy. Even when you consider that you can only see the cost you will pay is already ZCA is still very complicated, I will quote examples that costs are not so obvious unless you know the implementation details, which killed part of the advantage of being an abstraction. So many people think of the term as a cake recipe and not a questionable fact. The term is not a scientific norm, it is a market expression.If that were true then almost all languages would have ZCA. It is true that C is a language that this is quite true (I will not speak of Assembly because there has no abstractions that generate an extra layer of nothing), but not 100% true. All others have much lower percentages, although some more than others, C++ and Rust case, but not in all mechanisms.If the term was that last quote then it should be Controllable Cost Abstraction or something like that.C compared to C++ or RustSome will say that you wouldn't do anything in your hand more efficient than that, reaching the same goal, since the goal is to have something easier to use. This may be true, but it is an abstraction and has a cost.You can say that you are not required to use that and only pay if you use it, you have another more efficient way. It's also true, but it can't say that that mechanism is cost-free, it can still say that language can be cost-free, but it's only truth-free if programming as if it were C.Even this is an exaggeration because the C++ compiler generates a slightly heavier code even if it only uses C mechanisms. It is minimal, but it is not zero.The same happens with Rust, although in some things she is closer to C than C++. But it also has less powerful abstractions, Rust leaks more abstraction than C++ (if you want can leak in C++ too, and if you do it tends to get more efficiency in many cases).That's why language comparison tests don't help much, you can write a very efficient Rust code without using abstractions and a less efficient C++ using abstractions.ExamplesstringAn example is string C++'s, very powerful and easy to use, but you can't tell that it is always free of extra costs in relation to what is used in C. It usually makes a dynamic allocation that is very expensive without you or knowing (not always does). And it has optimization that makes it increase cost at another point.Most C++ implementations occupy 24 bytes no matter what they use. Some think it should occupy 32 bytes. With it small strings with even a certain size fit right there and everything looks great, except for the fact that you always have to analyze if it is a string short before doing something. If she's big there has the pointer to the place of heap where in fact will be string. That sounds good, it has interesting gains, but it has costs. That's a good abstraction, but it's not zero-cost. It's weird, the guy can be by value or reference. If you have multiple short equal texts you will have multiple instances, but if they are long it may be the same object. Can a simple reference be 24 bytes? WTF! Put that in one array and see the damage you do. Neither Java or C# or languages script They are often so inefficient at that specific point.And it's very used in places where you need to calculate one hash, you do not pay anything if you do not use, but if you use it will pay a higher price because you will have to calculate every time you need it, an indecency for a language that presses for performance.At least it is so in the default implementation, if you don't use it at all of this has cost, you can do your without problems and that you don't have the unwanted costs, but you will also have trouble using it with any standard library that expects you to string standard.Have you heard that in computing, as in life, (almost) everything is tradeoff?C# in 64 bits also occupies 24 bytes at least for a string (without counting the pointer in the original object of the reference(s), and grows fast as it adds characters. It is great abstraction, but it has cost, always requires dynamic allocation, but if it shaves, outside that there is no optimization for short text, it is more efficient than C++.Java arrived to have 40 bytes in 32bits, I do not know how it is today, but this is absurd, in many cases to store 1 or 2 characters (it will be larger).C has nothing of this cost, you decide where you want to allocate, although some say you should never allocate in stack, or even within a struct (some compilers do not even allow), everything great, but it does work, causes error, not always the programmer achieves the best efficiency, for example it can store as value and at some point may have to copy the data that can be too big, to compensate, or use a reference where causes licking.Not to mention the fact that you have to spend the size along with the text to make sure and be efficient (not the way we see it around that Comparing high-level languagesLanguages script connect little to typing, to where the data is being allocated, if you access it by value or reference, so they are easier, everything is abstracted and you pay for it, and you have no choice, have choices makes it difficult.And this generates more costs than people imagine, all data accessed is a potential danger, always needs complex processing only to take the data (some cases there are optimizations). For example, these languages do not usually have objects but rather structures https://pt.stackoverflow.com/q/429851/101 that pass by objects, this is a cost in various aspects.Java has already opted for a path that you have more type controls, from where it allocates, but well above. Not the same C#, especially in the newer versions that control is much higher, you may not pay certain costs if you use the most efficient mechanism.In C++ and Rust this goes further and gives more freedom of choice, eliminating much of the costs, and how it competes with C, if you choose this subset of language may have less cost yet, only losing, in some cases, to Assembly. Not all decisions are as you would like for a certain scenario.You can give up abstraction does not indicate that it has no cost, but some people think so.Is it something the programmer needs to know how to use or is it indifferent?Yeah, and no. A good programmer who cares about it should know and ideally he should research and see if he really is fulfilled what was promised, I already said he has a lot of marketing on it.If you need a lot of squeezing everything you can, you need to understand all the costs of all the mechanisms you're using and you can do it in a better way to achieve the ultimate goal of maximum efficiency. Not everything you're doing needs this.But who has to worry more is who makes libraries for others to use in an environment where they are cared for zero cost abstraction. If your library has no zero cost, no applications that use it, including other parts of the library will cost zero, it is contaminant.Is it really a 100% positive point?As far as I know, he himself, yes. Of course, if it does right, and if it is true and not illusion, or if it exists at one point but harms another.Being ZCA at one point can prevent being at another, see the example of string C++ I talked about. Note that others have some costs to avoid certain costs. But you can always claim that you can do as it is in C and have zero cost or make a type of yours where you have a cost only in what you really use. It's true, but that's worth any language, in C# you can create your type string with the commitments you want, the difference is that the normal type goes along even if you don't use it, although this will be true in almost all languages, only gives to give up a type so present if you give up everything that the standard library has.Is there no undesirable effect on the use of language by possessing this feature?Generally and clearly does not have, but language tends to be a little more complex to achieve this, I do not know if it is something bad, and even if it is, it is still something that may be necessary for other reasons.The building of the library is usually much more complex and the internal code is usually quite confusing because of this. If it's not such a confusing code, or language is too good, until it's true, or it doesn't cost zero in fact.It has compilers that make exceptions in the compilation when you know that there you need to whim to have a zero cost or at least lower than the normal one he would do. This is not always good, but gives an interesting advantage, it is a way not to create complexity in language to treat very specific cases. A typical case can be a string, a very used type that requires out-of-normal optimizations, and that can be easier because it knows in depth with what it is dealing with.You can write much more about it, almost every sentence opens the door to new doubts.