Closed stefanos82 closed 6 years ago
It's either C++98 or C++03 I'm not even sure I know. (Definitively not using C++11). I'm been only testing as far as Visual Studio 10 lately. If you have specific requirements maybe test with your compilers?
It's alright. I will experiment around it and see how it goes.
By the way, if you want to add an extra layer of security around NULL
, you can implement your own version that is really the same as nullptr
, but for C++98/C++03. Let's call it nil
:
const class {
// (private by default in classes)
// not allowed to get the address
void operator&() const;
public:
template<typename T>
operator T*() const
{
return 0;
}
template<typename T, typename C>
operator T C::*() const
{
return 0;
}
operator void*() const
{
return 0;
}
} nil = {};
That's it, really. Now, you can use it in place of NULL and have the same security as nullptr
.
Cheers.
P.S.: I don't quite remember which one of the two C++ gurus first implemented this; either is Herb Sutter's job or Scott Meyers' job; anyhow, it's working flawlessly.
Thanks! It'd be good to know. I haven't looked into the differences between C++98 and C++03. I suspect in practice it probably doesn't matter. C++11 and further are out of usable boundaries because not supported by many minor/obscure platforms.
So far we haven't had problem with the behavior of NULL. It's not really the coding style of imgui to use template magic when the behavior might not be obvious to the casual reader so I think I'm happy with using NULL as it is, but thank you for the suggestion. That trick is good to know.
The use of aforementioned nil
can be exactly the same with NULL
without the slightest difference. The real magic happens behind the scenes by the compiler itself, but nevertheless you can of course use whatever it works best with the project.
Is there anywhere a list, something like wiki page or something alike that lists the currently supported platforms?
I'm always interested in learning new technologies and systems that exist out there to help me broaden my technical horizons.
There's no wiki page of that sort. The list of supported platforms is basically any platform that can compile the code, since the library has little dependency. It has been used on all sort of video game consoles and embedded devices. Some can render it themselves, some can send the triangles back to the network to another machine for rendering.
That is good to know.
Regards to the patreon sponsoring, I was thinking to share my point of view which is what I have noticed happening for more than a year now with various projects out there.
Based on various FOSS-ed projects that I have been reviewing every now and then, they have received a plethora of suggestions by companies that are currently using those projects and all of them asked from those projects the same thing: a business invoice.
As a company they have stated, they are willing to pay for a product, but as a donation, they are hesitating to do so for some reason, which my guess is that it has something to do with taxes and legality overall.
My suggestion would be, why not follow the SQLite business model? Just take a look how they run their business and frankly, they are doing great based on the powerful clients they are currently supporting I must admit.
I think this concept is the ideal for dear imgui
and I'm sure companies would love to pay for professional support.
The best thing you can do is to send an email to companies that already use it and kindly ask for valuable feedback around this idea.
I'm more than sure they will gladly say a loud yes.
After much consideration and a bit of extra experimentation around my nullptr
implementation, I would like to withdraw my suggestion and kindly request to continue using the existing syntax dear imgui
is already using.
My only worry with NULL
is when you use it in an overloaded function that accepts integers and pointers. That's the case you should really use C++11's nullptr
to avoid ambiguity.
void foo(int);
void foo(int *);
void foo(char *);
void foo(const char *);
void foo(NULL); // Which one should it call? NULL is 0 in C++ for backwards compatibility with C
why should some one call a function with null pointer as an argument !!? .
@codz01 There are cases where such function includes a printf()
in it and the user might want to validate the function's calling and of course NULL
is a valid input wherever a pointer is taking place.
Closing this idle topic. As @stefanos82 is the person interested in knowing version of C++ between 98 and 03 is required and said he would look at it, if you do please post the result here, would be nice :) Thanks!
@ocornut Both flags -std=c++98
and -std=c++03
when used with GCC compiler, the following error is thrown:
../../imgui.cpp: In member function ‘void ImGuiTextBuffer::appendv(const char*, __va_list_tag*)’:
../../imgui.cpp:1605:24: error: incompatible types in assignment of ‘__va_list_tag*’ to ‘va_list {aka __va_list_tag [1]}’
va_copy(args_copy, args);
^
../../imgui.cpp:1598:36: note: in definition of macro ‘va_copy’
#define va_copy(dest, src) (dest = src)
^~~
Makefile:58: recipe for target '../../imgui.o' failed
make: *** [../../imgui.o] Error 1
When -pedantic
flag is used though along with std=gnu++98
or -std=c++11
and so forth, the following warnings are thrown:
warning: ISO C forbids conversion of object pointer to function pointer type [-Wpedantic]
So, in other words any flag that is greater or equally compatible with C99 will work as expected.
As we know by the standards, C++11 became compatible with C99 for backwards compatibility and C++14 with C11. Now about C++17 I don't know yet what kind of compatibility they will apply, we shall wait and see until June or July.
In other words, we need further feedback around this and if indeed it depends on C++11 for compilation, then my suggestion would be to fully implement the code in C++11 to take advantage many new and useful features that would improve code both in readability and in a more secured way.
Your opinion, let alone your objective though it has nothing to do with my naive, yet sincere suggestion.
Cheers.
That va_copy error is not really a C++ version related error, more like a "GCC/glibc support of C++ versions" error. Annoyingly va_list
is defined __va_list_tag [1]
in the libc header file, so the va_list parameters and the local variable using va_list can't be just copied to each others.
See http://stackoverflow.com/questions/8047362/is-gcc-mishandling-a-pointer-to-a-va-list-passed-to-a-function
I don't know how to fix it yet. Probably won't try to fix it until an actual real user needs it, rather than a hypothetical use case of testing for various flags you wouldn't actually use.
Allow me to disagree with you @ocornut. It definitely is a C++ version related error.
As you can see from this link http://en.cppreference.com/w/c/variadic/va_copy, you can see it says (since C99)
and by using a C++ flag that is less than C++11 -- which is compatible with C99 by the ANSI / ISO standards -- it means the least version used with dear imgui
should be C++11 or gnu++98
, flag-speaking if we go with GCC compiler that is, to avoid producing such error messages.
I wonder if va_copy exists as a function (not a macro) with your settings where is fails, and therefore we are redefining it. Does removing the block that defines a default va_copy works with those settings?
I didn't edit any kind of code; all I did was to run both OpenGL examples inside examples
directory you provide with dear imgui
and got these results.
That's why I am asking if removing the block that default a default va_copy in imgui.cpp would fix it that with configuration?
Can you please be more specific?
Did you mean to comment out the following lines
#ifndef va_copy
#define va_copy(dest, src) (dest = src)
#endif
that are located in lines 1597 to 1599 or did you mean something else?
Your enlightenment around this topic would be of great help.
@ocornut OK, I have managed to work around it, but I have only tested it with GCC and Clang.
You just need to replace va_copy(args_copy, args);
in line 1607 of imgui.cpp
with __builtin_va_copy(args_copy, args);
if you want and will compile just fine with C++98.
But let's make things simpler as they should have been in the first place:
#if defined(__GNUC__) || defined(__clang__)
#undef va_copy
#define va_copy(dest, src) __builtin_va_copy(dest, src)
#endif
Place this piece of code just below #ifndef va_copy
that you wrote for versions prior to Visual Studio 2013 and your code should work as expected with all sorts of C++ versions.
Besides, that is what /usr/lib/x86_64-linux-gnu/6/include/stdarg.h
it's implementing for C99 and C++11 as you can see for yourself:
...
#if !defined(__STRICT_ANSI__) || __STDC_VERSION__ + 0 >= 199900L \
|| __cplusplus + 0 >= 201103L
#define va_copy(d,s) __builtin_va_copy(d,s)
#endif
#define __va_copy(d,s) __builtin_va_copy(d,s)
...
So basically we are "hacking" around the standards so to speak to accomplish a backwards compatibility with old C++ standard, like that of C++98.
Thank you for digging it. Those things are particularly tricky to get right for every compilers/lib/versions combo indeed.
Mainly OT, but if you want imgui to be further more portable...
Compiling with Visual C++ Toolkit 2003 (it was the first Microsoft compiler with dot Net support, the only one that Microsoft released as a command-line package at the time (not now)), I get:
../../imgui.cpp(973) : error C3861: 'vsnprintf': identifier not found, even with argument-dependent lookup
../../imgui.cpp(984) : error C3861: 'vsnprintf': identifier not found, even with argument-dependent lookup
../../imgui.cpp(1607) : error C3861: 'vsnprintf': identifier not found, even with argument-dependent lookup
that can be fixed simply with something like:
#ifdef _MSC_VER
#if (!defined(vsnprintf))
# define vsnprintf _vsnprintf
#endif //if (!defined(vsnprintf))
#endif //_MSC_VER
P.S. I've assumed vsnprintf is always defined as a macro (when it's present) in the code above. Otherwise we could make deeper version checks:
MSVC++ 14.1 _MSC_VER == 1910 (Visual Studio 2017)
MSVC++ 14.0 _MSC_VER == 1900 (Visual Studio 2015)
MSVC++ 12.0 _MSC_VER == 1800 (Visual Studio 2013)
MSVC++ 11.0 _MSC_VER == 1700 (Visual Studio 2012)
MSVC++ 10.0 _MSC_VER == 1600 (Visual Studio 2010)
MSVC++ 9.0 _MSC_VER == 1500 (Visual Studio 2008)
MSVC++ 8.0 _MSC_VER == 1400 (Visual Studio 2005)
MSVC++ 7.1 _MSC_VER == 1310 (Visual Studio 2003)
MSVC++ 7.0 _MSC_VER == 1300
MSVC++ 6.0 _MSC_VER == 1200
MSVC++ 5.0 _MSC_VER == 1100
[EDIT:] vsnprintf is present in imgui_demo.cpp as well.
@Flix01 I have no idea how Microsoft is implementing its compiler(s), but what I know for sure is that it took them years to partially support many C99 features and still it's not fully compliant. Now why they do such thing it's beyond my understanding.
@ocornut Remember when I asked for a wiki page with all compilers being used to compile / test dear imgui
?
Now it's a good time to get one so we can see which compilers support what builtin flags.
@ocornut off topic: I have sent a pull request about something you might be interested to look at https://github.com/ocornut/imgui/pull/1093
@stefano82 Actually from the cpp reference it seems that vsnprintf has a version before C99:
int vsprintf( char *buffer, const char *format, va_list vlist ); (until C99)
So @ocornut was probably right to assume that every compiler should have it defined.
But you're right too, about "things beyond understanding" in Microsoft compilers.
@Flix01 true, but in http://en.cppreference.com/w/c/io/vfprintf we can see the same version implemented with an extra keyword added to stream
and format
, named restrict
which this keyword is not implemented in C++ by the standards, still though compilers such as GCC, Clang, and Visual C++ have workarounds:
__restrict__
for GCC and Clang__restrict
and __declspec(restrict)
for Visual C++In other words, I firmly believe dear imgui
should be C99 / C++11 compliant as it eliminates certain restrictions from the developer and the compiler, plus C99 it's supported on a large range of devices if we take into consideration the Linux kernel that depends on C99 / GNU99 flags.
What do you think @ocornut ?
@stefanos82
I firmly believe dear imgui should be C99 / C++11 compliant
I don't agree: I think broader compiler support is the best choice. (But I'm not @ocornut)
@Flix01 I didn't say I disagree with you.
It would be nice though if we could take advantage of so many useful C++11 features that help the developer to produce cleaner, safer, and much more readable code than the macro madness coding style we can see in legacy code.
If that is the case, then the project should be rewritten in C89 and forget about C++'s convenience.
We are in the middle of 2017 and we should be looking forward, not backwards.
The majority of IoT devices are already using Node.js that is implemented in C++11 and that alone is an evidence that C++11 is used in multiple platforms.
I understand your concerns though and I can pretty much empathize with you.
I wonder who uses ImGui that needs old C++? Perhaps people using on things like PS3? What C++ version does PS3 SDK support?
@ocornut Remember when I asked for a wiki page with all compilers being used to compile / test dear imgui?
Now it's a good time to get one so we can see which compilers support what builtin flags.
@paulsapps As you can see, I have quoted this for you to show that I have asked @ocornut more or less what you are asking about old C++.
I think it's something dear imgui
needs to have - as a resource I mean - to know where the development should get directed the most.
It reminds me an old proverb of ours that approximately translates to "follow the flow where the money leads". That is what project's development motto should be.
My last post here (it's a kind of discussion where everybody can have good reasons to defend his position, so it can be never ending).
Dear Imgui is a two cpp files library. It makes sense to have the broadest possible compiler compability as a priority in my opinion.
People can already use C99/C++11 in the code that uses Dear ImGui.
There is a certain amount of the macro madness, but it's not that much of a mess.
I really don't understand why we should raise the requirements of these two files.
I'm not sure if maintainers of ImGui ports in other languages (e.g. C#,python,Lua) will be happy with it.
My last post here (it's a kind of discussion where everybody can have good reasons to defend his position, so it can be never ending).
- Dear Imgui is a two cpp files library. It makes sense to have the broadest possible compiler compability as a priority in my opinion.
Agreed on this point.
- People can already use C99/C++11 in the code that uses Dear ImGui.
That is something I didn't know as I have recently found out Dear ImGui, thank you for letting me know.
- There is a certain amount of the macro madness, but it's not that much of a mess.
The less the better. If it's inevitable...oh well ¯\_(ツ)_/¯
- I really don't understand why we should raise the requirements of these two files.
I could ask the same kind of question for all these countless programming languages and frameworks that pop up all over the place like mushrooms that fix not a single problem, other than pleasing original creators' ego and pride.
- I'm not sure if maintainers of ImGui ports in other languages (e.g. C#,python,Lua) will be happy with it.
Is it something @ocornut should really care about? That is, does Dear ImGui
depends on these projects to function?
It sound harsh, but that is what Linus is ranting about if we compare it with Linux's development.
If a project maintainer starts hearing each and everyone's demands and wants, the project will never get fixed nor will it ever reach stability, let alone becoming feature-complete.
If Dear ImGui
wants to stay with C++98 standards, no problem. But if it depends on lower level code, like that of C99's va_copy
, then I would say it would be better to go with C++11 since it is backwards compatible with C99.
That is just my own opinion and I do tend to firmly support my believes; it doesn't mean I am correct nor that anyone should follow my path or my way of thinking.
I know that through constructive criticism and academic interest, incredible things can happen.
+1, was trying to build with -std=c++03
as per a suggestion on #1962 and hit the error on both GCC/clang.
@franciscod I tested with mingw64 under Windows and g++ -std-c++03 worked, Clang gave other errors but not something related to va_copy().
Could you 1) post the log, and 2) try to replace the va_copy definition block with:
// On some platform vsnprintf() takes va_list by reference and modifies it.
// va_copy is the 'correct' way to copy a va_list but Visual Studio prior to 2013 doesn't have it.
#ifndef va_copy
#if defined(__GNUC__) || defined(__clang__)
#define va_copy(dest, src) __builtin_va_copy(dest, src)
#else
#define va_copy(dest, src) (dest = src)
#endif
#endif
And see if it fixes it?
@stefanos82 I pushed a va_copy fix but I couldn't find a way to repro the error you mentioned here: https://github.com/ocornut/imgui/issues/1085#issuecomment-296302826 Can you still repro it? I tried with GCC and Clang under Windows, 64-bits with -std=c++03
@franciscod It's committed now so if you can confirm the fix it would be ideal.
@Flix01 Committed a change for _vsnprintf() under Visual Studio. I'm not super sure about it but I guess if it causes other problems we'll find out.
@ocornut Those warnings were taking place under GNU / Linux Debian testing 64-bit.
With the latest commit, no more warnings for me.
I have checked it with both GCC 8.1.0 and Clang 6.0.1 and works flawlessly.
Thank you @ocornut :+1:
Works here too, GCC 8.1.1, clang 6.0.1.
Wonderful, closing this!
First of all, congrats for this amazing project; it really looks both awesome and promising.
Now, as the title says, which C++ version is supported by default?
I'm asking, because I took a look at the code and looks like a hybrid of C89 with C++98.
Can someone enlighten me please?
Thank you.