Advertisement

Cairo suggested to be included in ISO C++

Started by January 11, 2014 10:58 AM
12 comments, last by Servant of the Lord 10 years, 9 months ago

It has been suggested that a wrapped version of the Cairo 2d graphics library (http://cairographics.org/) might be up for inclusion in ISO C++.

http://developers.slashdot.org/story/14/01/04/2115249/cairo-2d-graphics-may-become-part-of-iso-c

I'm undecided on how to feel about this. On one hand, I like the Cairo API, it's really good at what it does. I also think that one of the biggest issues with C++ is that the standard library doesn't have as much stuff as some other languages libraries do.

On the other hand, some part of me feels that providing 2d graphics is outside of what I always considered the scope of ISO C++.

So, not sure what to think. What do you think? Good? Bad? Doesn't matter?

Huh, weird. Does that mean a standards complient runtime library for a hardware without graphics will have to include a dummy renderer?

Advertisement

Huh, weird. Does that mean a standards complient runtime library for a hardware without graphics will have to include a dummy renderer?

I haven't used Cairo, but looking at it briefly, it seems to support multiple types back-ends, ranging from hardware rendering, to memory buffers, and to vector graphics formats such as PDF files. You don't need a graphics hardware, or even a display, for Cairo to make sense in this case. How the standard committee intend to handle this, and what kinds of output they intend to require, if any, is a different question though.

I think domain-specific applications lie outside the scope of a language.

Central planning is great for some things, especially when mindless masses need to be have their needs met. Among the strongest reasons for the widespread and continuing use of C++ are that (1) it adopts existing infrastructure rather than forcing the existing infrastructure to be adopted (that's the C legacy support), and (2) it encourages an open marketplace of implementation ideas.

When C++ was first popularized, graphics displays were expensive niche devices. If a graphics library had been a mandatory part of the language runtime, we'd probably be running software written in Ada on our routers and toasters, because the waste of including the 1990s-era graphics runtime in something that can leave one side of your bagel still soft and chewy would be a prohibitive cost and C++ would have been a non-starter. Similarly, the cost of embedding a 2010-era graphics runtime in your 2030-era Martian atmosphere rebreather will be prohibitive.

One of the fundamental design tenets of C++ was "pay only for what you use." Adding in a bulky domain-specific runtime into the standard library forces everyone to pay for stuff even if they don't use it. Central planning with distributed costs is just not the C++ way: it's a major distinguishing factor between C++ and almost all the competing languages. I can only hope the central committee members keep their senses and do not forget that.

That said, we use Cairo for our work and it's a typical Gnome-style C API. Using it as a basis for a decent C++ graphics library API design is not a tragedy. Mechanically adopting it wholesale and integrating it into the C++ standard would be a serious mistake.

Stephen M. Webb
Professional Free Software Developer

my thoughts on this:

on one hand, standardized APIs are a good thing, as they help with things like cross-platform compatibility and similar;

on the other hand, it doesn't really belong either in the core C or C++ runtimes, which have generally consisted of things which are pretty much "core", which the majority of applications are likely to need and make use of.

I don't really think Cairo fits in with the latter case, since at that point we almost may as well add OpenGL and GTK+ and similar to the core language as well.

better I think would be if there were a separate set of standards for this, more in a similar sense to POSIX.

or, hell, even getting POSIX to be better supported cross-platform (such as on Windows).

though, something that is worrying with some of this, is that the stuff being proposed and added to the recent standards, is often not so much stuff that is widely used or even necessarily desired by most programmers, but fairly often things that are the personal pet projects of the standards committee members (and, in a few cases, some features remained largely unimplemented by compilers, and were later demoted to optional features, ...).

well, and companies pushing for patented features being added to standards and similar, ...

this is one area I think de-facto standards are better, as they are more likely to have been widely agreed on, and usually less likely to be patent encumbered.

or such...

Though I'm not familiar with Cairo in specific, the idea of broadening the C++ Standard Library extensively was talked about at Going Native 2013.

I think (re-skimming through it), that this is the talk [YouTube version]. (You can skip the first 10 minutes or so - Microsoft specific compiler info)

A year earlier (Going Native 2012), this talk was given. You can skip to 1:11 for where the relevant (to this discussion) subject is brought up.

For anyone who hasn't heard about Going Native, I heavily suggest watching the videos for both Going Native 2013 and 2012. Very very thought-provoking and insightful tips for C++, even if you don't agree with all of it. I feel like it definitely was valuable for me to watch the vids, though it took me a week to work through each conference. laugh.png

C++11 was a major release, C++14 is a minor release, C++17 is going to be a major release, but focused on broadening the standard library.

This is one of the slides shown during the video:

CppPortableLib.jpg

On the left: The size of the Java core language, the C# core language, and the C++ core language.

On the right: The size of the Java standard library, the C# standard library, and the C++ standard library.

The speaker (the same Herb Sutter who's reaching out to the Cairo userbase, who heads up part of the standards committee) quickly goes on to say, "More does not equal better", but then explains why he thinks it is important for C++, and also that not every new part of the standard library will be beneficial to every developer, but that the standard library can be diverse enough to accommodate different industries by adopting and standardizing existing mature libraries (just as they do with Boost).

In some cases, this might be great, and in other cases it might be better to not standardize certain kinds of libraries, but they are looking into it. Not just Cairo, but alot of different libraries that are already well-adopted, well-designed, mature, and generically flexible, but specific enough to be useful.

Qt was mentioned as an example (because it is huge collection of high-level libraries, and not merely a GUI library), Boost also, POCO, Cinder, openFrameworks as well (the last three were knew to me, but are widely used by non-videogame developers in some industries). Facebook's open-source libraries, some of Google's, etc...

Then, take them, and give them consistent interfaces, and using consistent types. Unless you enjoy converting between three different types of string classes, seven types of 2D vector/point classes, a two-dozen integer naming schemes, and (even worse) entirely different architectures, messaging systems, and high-level interface designs.

PCL.jpg

(Note: PCL.org is the wrong URL. PCL stands for, 'Portable C++ Library' in this context - I'm guessing the correct URL is isocpp.org, at least temporarily)

Now, nobody is saying copy+paste all of these into the standard... but, they are talking about existing work that has already been refined and refined again, work that is already open and free and unencumbered by licensing or patent issues, and taking the portions that it makes sense to take to ensure that every C++ compiler (where it makes sense) has support for it out-of-the-box, so you can be guaranteed that your code using X and Y are cross-platform with well-specified behavior.

This has to be done carefully, slowly, and with much thought given to the future (once in the standard it is very hard and undesirable to remove something, so alot of fore-thought must be put in).

The idea is a good one - it's just a question of what libraries (or sub-portion of libraries), what features, should be standardized? I'd like to see it modularized, so including, for example, <graphics2D> (i.e. Cairo), can be packaged as a whole or not packaged as a whole by compilers, depending on whether it makes sense for the platform the compiler is targeting. That is to say, when building a compiler, part of the compilation process could include checking off which Standard Library components should be built and packaged with it, IMO.

If you have an opinion about it, the standard committee is begging you to tell them and to get involved in the discussion. They want your (well-thought out and well-reasoned) feedback. Most the standard committee members work at Microsoft, Adobe, Google, Apple, and Facebook and work on opensource projects like Clang and Boost. They need and want diverse opinions from people in many different industries, because C++ is heavily used by many industries, including our game industry, that they have very little knowlege about

This is really just the beginning of a discussion about these subjects. Cairo won't be slapped together and packaged with C++ overnight. The earliest we are talking about is 2017 (three years from now), which is a lengthy discussion - which will mostly be focused on: Should they include it at all? What parts? How should the interface be redesigned? If not the 2017 date, these libraries would probably start showing up in the 2020 standard (if they manage to hold to the major-minor-major-minor every-three-years plan that they hope to).

lrha.png

Whether PCL (Portable C++ Library) becomes a consistent, organized, collection of higher-level libraries that are merely supported by all the major compilers on all the major platforms, or whether PCL actually gets officially standardized will probably be a big part of the discussion going forward.

izfb.png

Advertisement

re: PCL

This is a proposal to create a de jure standard of de jour technologies. Just imagine what would have happened if this was done in 1995 alongside the original C++ standard. We'd have both token ring and SNA networking available, and they'd be guaranteed to be operable in 640 kilobytes of memory or less. Far and near pointers would be mandated.

Here at work we're already moving away from JASON as obsolete technology, and JASON was seen as a replacement for XML. An ISO standard for such things is good because it'll keep those busybodies flying to all kinds of exotic locations and busy writing documents, and otherwise would be ignored.

Stephen M. Webb
Professional Free Software Developer

The proposal is at http://isocpp.org/files/papers/N3888.pdf

Huh, weird. Does that mean a standards complient runtime library for a hardware without graphics will have to include a dummy renderer?

Yes Herb Sutter is leading up this SG, he announced this last Going Native conference, C++14 and 17 and onwards will see much more of a focus on std lib then on new language features. ISO C++ wants to move into a direction like .NET where most of the common tasks you want to do are part of the C++ framework.

He said he was leading the Studie Group( aka SG ) for a 2D framework to be included in the std lib of C++, others are transactional memory and multithreading and network libraries, database connections. As Servent suggest watch the Going Native videos to see where C++ is intending to go there are some really interesting things in there.

These SGs will be brought in once they have a working version of the subject and some of them are going to be included in C++14 already others will come in at C++17 or later.

Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2, theHunter, theHunter: Primal, Mad Max, Watch Dogs: Legion

If you want Cairo, you can always download it and link to it, what's the matter with that. Let's say I want MP3 support, is that going into the next standard too? Support for computer vision would be nice, don't you think?

I'd prefer if they'd put more work into the actual language, and I'm not talking about WTF updates like the one that is to come in C++14 about separators in literals which makes it legal to write literals like 1''2'345'67''''8'9. Really? Couldn't they think of something even less useful?

I'm not saying that C++11 (or C++14) is really bad. It's a good-willed attempt, but there remain a lot of things that I wish were a bit more "round" or "polished".

type_info had a hash_code function added in C++11. Finally, something really useful about RTTI, making serialization a lot easier. Except... except it's not really useful for anyting (anything including serialization, it's only useful as key in a hash table). The hash isn't a compiletime-constant, not even for builtin types. You have to wonder, do you expect the type of, say, int to change during runtime? But worse, the standard explicitly allows for different invocations of the same program to return different results (WTF?). Same input, different output. Seriously?

Would it really be asked too much to require that different invocations of the same program return at least the same value?

enums could be more intelligent. You still can't figure how many enumeration values are in one enum or what their names and values are, for example. How nice would it be to bind constants to an embedded script language if you could write something like: for(auto i = 0; i < that_enum.size(); ++i) context.bind(that_enum.name(), that_enum.value()); Or, why not for(auto e : that_enum) { ... }.

Sure, this is somewhat grossly different from what present C++ looks like, but what is the hindrance? C++11 looks grossly different from C++03 too. An enumeration isn't an array, nor is it a class with member functions, OK... but so what? Actually why can't a complete enum behave like an array with accessors to names and values? None of the necessary information is something that the compiler does not already know or that the compiler couldn't trivially replace with a compiletime-constant.

Also, the strongly typed enums in C++11 are more annoying than helpful most of the time. It's nice that identical names don't collide now. But in many (most? all?) cases, you only want exactly one enum in one place (be it inside a scope or in a function call), and it is a nuisance having to type a fully qualified name, expecially if you give your enumerations expressive names that are longer than 3 letters. I concede that it is non-trivial for a compiler to magically figure out just what you want, but it's something you might be able to hint nevertheless, maybe with an attribute, or with a keyword ("explicit" or "using" sounds good).

If you declare, say, a function like open_file(string name, open_mode_t mode), then you declared that you expect a constant of type open_mode_t, you do not care whether the enumerator read in open_mode_t collides with the enumerator read in memory_protection_t or with any other enumeration. Actually, even if you don't tell anything special about it, this is pretty clear. You've said what type you expect. Even if the compiler has several ambiguous possibilities in its books (and, unlikely as it may be, several function overloads taking different enums), only exactly one is applicable due to the requested type. Yet, in reality, you still need to type open_mode_t::read, simply because the language works that way. You can't do something like using enum open_mode_t; inside the function's body either (works fine for namespace, why is it not allowed for enum?).

If my hypothetical function open_file does not cut it, look at APIs like OpenGL where you still use macros for constants because there is no way of doing it properly with enums (even though the spec file would in the mean time easily allow for it!). That's of course because there's no way to declare two non-strong enums that both have GL_ONE or GL_SOURCE (or the like) in them.

There should be a way of telling that you want exactly one particular type of enum in a particular location, so the superfluous resolution is not needed. Maybe a declaration similar to void foo(using blah blubb); to denote to the compiler: Here, please do as if I wrote blah:: in front of everything I provide as input to blubb, because that's the only type/strong enum/namespace I care about here. Whatever the actual syntax may be... but there should be some way of not requiring you to type redundant stuff that is, at least to the human, obvious.

Similarly to strong enums, constexpr was a good intent, but often turns out counterproductive rather than useful because the standard imposes ridiculous limitations which force you to write inefficient recursive implementations (though C++14 will address this!) and compilers are not required to evaluate something that is constexpr and constant in every respect at compiletime. The compiler isn't even required to remember the compiletime constant for a second time after you have forced compiletime-evaluation by assigning to an enumeration before (and e.g. GCC demonstrably doesn't do that!).

C++14 will bring template variables (seriously, who needs that... but alright, it doesn't hurt) --- but templates can still only take a typename or an integer (or bool). They can't take much else, in particular not a float constant (yes I am aware of rounding/precision issues, but so what), nor a character string literal, nor a particular typename. Why not? Why does a typename have to be every typename?

If you write a class like, say, std::lock_guard, which expects a particular type with a particular behavior (in this case something it can lock/unlock), you declare it as template<typename Mutex>. If a user supplies a type that doesn't have the necessary functions, there will be a compiler error because of missing functions.

But, would it be asked too much if you were allowed to write <lockable Mutex> instead of <typename Mutex> and have the compiler treat this in a way similar to forward-declaring lockable (or whatever it takes for the compiler to "remember" what you ask for), and to static_assert upon instantiation that whatever type the user supplies is what you mandated? Preferrably with a human-intellegible error message which isn't something like "missing function", but something like "bad template parameter given".

C++11 has thread and mutex support and flipping condition variables, but no semaphores. There's an atomics library, but no simple atomic containers like a queue or a list (not an issue for me, personally, but seriously... why not? This is what 99.9% of people get wrong 99.9% of the time, if there is one thing that would be truly useful for a standard library, it's something that is hard / error prone to implement).

Static locals are initialized thread-safe thanks to C++ knowing about threads. Fine, that's on the safe side. But what if you don't want that? What becomes of "pay for what you use" when you use a static local and do not share it among threads?

All in all, lots of good ideas, but still a lot to polish before another half gigabyte of library is being added.

This topic is closed to new replies.

Advertisement