This is the mail archive of the mailing list for the GCC project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [C++11] Reclaiming fixed-point suffixes for user-defined literals.

On 05/11/11 21:43, Gabriel Dos Reis wrote:
On Sat, Nov 5, 2011 at 2:30 PM, David Brown
A C++ template class for "_Fract" support would be straightforward to write,
and could easily support the formats in N1169.  But it would be very hard to
do so in a way that generates small and fast code without resorting to
inline assembly for targets that have hardware support for such features.

is this some sort of "here an outlanding statement and you would have to prove a negative to prove me right" or do you have more factual evidence to back your statement?

It is an estimation.

Some processors have particular instructions or mode flag settings that let them handle fixed point data very efficiently, such as by doing multiplication and shift at the same time, handling saturated arithmetic, or using special "accumulator" registers for particular features.

It is certainly /conceivable/ that gcc will generate such instructions automatically, but I would be very surprised - and extremely impressed.

Take an example using a processor I know well, the AVR (it is an 8-bit device, which is a little unusual for gcc). It has an instruction will multiply two "1.7" signed 8-bit integers to get a single 1.15 signed 16-bit integer - basically combining an 8-bit x 8-bit to 16-bit multiply with a left shift. So to do a "signed short _Fract" multiply, you have a single instruction and discard the least significant byte.

Simulating the same operation in generic C would be something like :

int8_t multShortFract(int8_t a, int8_t b) {
	int16_t c = (int16_t) a * b;
	return (c >> 7);

Now, I have enormous respect for the gcc (and related libraries and tools) developers, and I am regularly surprised by how smart the compiler is. But using such features of the target requires specific code.

The advantage of using C's "signed short _Fract" here is that gcc /will/ use the optimal instruction in such cases (assuming, of course, that support is added for the target in question). If it doesn't have such support, it can do the calculation using something similar to the C above - slower but correct.

As you say, it is possible that both could be supported - using a template
class to provide a generic solution, and using the C "_Fract" types for
specialized classes.  The first step to that, however, is to allow the
standard C "_Fract" types to work in C++ as a gcc extension.

The same principle applies to the decimal types and extended float types
supported by C.

that is one possibility. However there is a difference between restricted "extension" and full fledged extensions. I can see how a restricted version would work in C++ as an extension, but I doubt that is what you want. I can also see how unrestricted extension (which you seemed to advocate) brings more headache where a library solution is seamless.

I am not sure what you mean by a "restricted extension" and a "full fledged extension". But I do appreciate that extensions cause issues that libraries do not.

Keeping adding builtin type specifiers to a language is not a
sustainable and responsible way to grow a large language
for the real world.  I appreciate we may disagree on that point.

It is always difficult for people to see all aspects of something like this - and it is important to do so when figuring out what to implement. That's what discussions like this are for!

Let me try to put forward the viewpoint of the embedded programmer, since these are the people who would use such features. I fully appreciate that other people see things differently, and that there are often good reasons for doing something that seems wrong from my viewpoint. And I also fully appreciate there is a very big difference between agreeing that something is the best solution, and actual implementation.

In embedded systems, C is often used for smaller systems, with bigger systems using C++. There are also people who use C for big systems, and those that use C++ for small systems. And lots of code is a mixture.

The key issue is that it is, quite frankly, a pain in the a** that C++ is not closer to a superset of C. Originally, C++ was a superset - excluding a few points that can easily be avoided in well-written code. These days, the two language standards have moved gradually further away from each other. Obviously C++ is going to get features that C does not - that's fair enough. But it is seldom that there is a good reason for C++ not supporting the additions to C standards.

Some of the differences are just mind-boggling - C1x has got a "_Static_assert" addition, while C++11 has "static_assert". They do the same thing, but have a different keyword. Don't these people /talk/ to each other? Do they make differences like this deliberately to annoy people - both users and toolwriters?

gcc has always countered that to some extend, by allowing additional C features to be used in C++. But even there there are limitations - there are plenty of gcc extensions to C that are very useful, and for some reason only work in C and not C++.

As a programmer, when I write portable code in C I want it to be valid C++ as well. This gives the most flexibility, and the most efficient use of my code. I don't want to have to re-write code to do the same thing in each language, or to re-learn the differences.

So to make "_Fract" and "_Accum" really useful, I need to be able to use it in C and C++ code, and know that the types are compatible across the two languages, and that the generated code will be equally efficient. Frankly, as a user I don't really care whether it is implemented by a C++ library, a gcc extension, mind-numbing macros, or whatever. It is absolutely fine if the details are hidden within a "stdfix.h" header file. But what I /don't/ want to end up with is a type called "signed short _Fract" in C and "_fract<8>" in C++, or being unable to pass data between the languages, or having to have C++ call external C functions just to get efficient implementations.

Sorry for the rant - it is not aimed at you or anyone involved in gcc,


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]