- Available C++ Libraries FAQ - 1 Update
- On the explicitness of it all - 1 Update
- why inline function doen't "inlined" - 10 Updates
Nikki Locke <nikki@trumphurst.com>: Feb 14 11:23PM Available C++ Libraries FAQ URL: http://www.trumphurst.com/cpplibs/ This is a searchable list of libraries and utilities (both free and commercial) available to C++ programmers. If you know of a library which is not in the list, why not fill in the form at http://www.trumphurst.com/cpplibs/cppsub.php Maintainer: Nikki Locke - if you wish to contact me, please use the form on the website. |
Daniel <danielaparker@gmail.com>: Feb 14 02:43PM -0800 Is there a reason why explicit basic_string(std::basic_string_view<CharT, Traits> sv, const Allocator& alloc=Allocator()); // (1) is explicit, but operator std::basic_string_view<CharT, Traits>() const noexcept; is not? I can't see a particular reason for making (1) explicit, considering that the constructor that takes const CharT* s is not. Thanks, Daniel |
wij@totalbb.net.tw: Feb 13 07:05PM -0800 On Wednesday, February 14, 2018 at 12:34:03 AM UTC+8, James R. Kuyper wrote: > If you want sin2 to be an expression that points to the same function as > ::sin, that's easy to arrange: > auto const sin2 = ::sin; What has presented is a (mis)reduced version of the real problem, because the result is different from file to file, difficult to reproduce (and I almost forgotten I can't expect the address of inlined function be identical ,not by what the standard says but by the semantics, or user's common understanding. Actually, I were trying to wrap ::pow10 (manpage says this is a GNU extension) namespce Ns { inline float pow10(float v) { return ::pow10f(v); }; inline double pow10(double v) { return ::pow10(v); }; inline long double pow10(long double v) { return ::pow10l(v); }; }; To keep things in topic, I tried evaluate "auot const sin2=::sin;" in older style: typedef float (& Math_f)(float); typedef double (& Math_d)(double); namespace Ns{ const Math_f pow10(::pow10f); const Math_d pow10(::pow10); }; But: $g++ file.cpp file.cpp: error: conflicting declaration 'double (& Ns::pow10)(double)' const Math_d pow10(::pow10); So, this problem is still hanging there! |
Jorgen Grahn <grahn+nntp@snipabacken.se>: Feb 14 06:49AM > On Wednesday, February 14, 2018 at 12:34:03 AM UTC+8, James R. Kuyper wrote: ... > What has presented is a (mis)reduced version of the real problem, Yes, I wondered what you really wanted to do. > inline double pow10(double v) { return ::pow10(v); }; > inline long double pow10(long double v) { return ::pow10l(v); }; > }; [To non-Linux readers: these three GNU functions take a float, double and long double respectively.] Well, that code looks simple and correct to me. (Except I'm not sure which overload is picked if you call Ns::pow10() with an int or similar.) I didn't have time to understand the rest (below) though. What do you need it for? > file.cpp: error: conflicting declaration 'double (& Ns::pow10)(double)' > const Math_d pow10(::pow10); > So, this problem is still hanging there! /Jorgen -- // Jorgen Grahn <grahn@ Oo o. . . \X/ snipabacken.se> O o . |
Ian Collins <ian-news@hotmail.com>: Feb 14 08:09PM +1300 > inline double pow10(double v) { return ::pow10(v); }; > inline long double pow10(long double v) { return ::pow10l(v); }; > }; Using inline, which is only a hint, is pretty pointless here. First off the functions probably will be inlined and secondly even if they weren't, the call overhead would be insignificant. You will also hit ambiguity problems with calls like "pow10(2);" or passing anything that isn't a floating point type. Finally, loose all those superfluous semicolons! -- Ian. |
"James R. Kuyper" <jameskuyper@verizon.net>: Feb 14 08:50AM -0500 > On Wednesday, February 14, 2018 at 12:34:03 AM UTC+8, James R. Kuyper wrote: ... > reproduce (and I almost forgotten I can't expect the address of > inlined function be identical ,not by what the standard says but > by the semantics, or user's common understanding. That's true only of inline functions with internal linkage - a separate actual definition of such a function will be created for each translation unit in which you take it's address. However, "... An inline function or variable with external linkage shall have the same address in all translation units. ..." (10.1.6p6). > $g++ file.cpp > file.cpp: error: conflicting declaration 'double (& Ns::pow10)(double)' > const Math_d pow10(::pow10); The problem is that Ns::pow10 is a reference to a function, it's not itself a function. As a result, it cannot be overloaded. If you need overloading, you'll have to define wrapper functions, and the wrapper functions will unavoidably have addresses (if you take their addresses) even if inlined, that are different from the addresses of the function they wrap. That's not a problem - calls to one of the wrappers will still be inlined. And if the existence of the actual functions wasting space bothers you, remove the code that takes the address of those functions - then the compiler will have no need to create them. |
wij@totalbb.net.tw: Feb 14 06:41AM -0800 On Wednesday, February 14, 2018 at 3:09:28 PM UTC+8, Ian Collins wrote: > Using inline, which is only a hint, is pretty pointless here. First off > the functions probably will be inlined and secondly even if they > weren't, the call overhead would be insignificant. These codes are in a header file. If definition is given and not inline, complier would say multiple definition error. > You will also hit ambiguity problems with calls like "pow10(2);" or > passing anything that isn't a floating point type. Is'nt that ambiguity problem for all kind of function overloads? > Finally, loose all those superfluous semicolons! For detecting language changes, at least. |
wij@totalbb.net.tw: Feb 14 06:53AM -0800 On Wednesday, February 14, 2018 at 9:50:37 PM UTC+8, James R. Kuyper wrote: > translation unit in which you take it's address. However, "... An inline > function or variable with external linkage shall have the same address > in all translation units. ..." (10.1.6p6). How unfortunate! > will still be inlined. And if the existence of the actual functions > wasting space bothers you, remove the code that takes the address of > those functions - then the compiler will have no need to create them. I was surprised for a moment that such overloading problems can be solved by reference overload. Probably future C++ might consider adding such function reference overload. |
"James R. Kuyper" <jameskuyper@verizon.net>: Feb 14 10:19AM -0500 > On Wednesday, February 14, 2018 at 3:09:28 PM UTC+8, Ian Collins wrote: >> On 02/14/2018 04:05 PM, wij@totalbb.net.tw wrote: ... >> weren't, the call overhead would be insignificant. > These codes are in a header file. If definition is given and not inline, > complier would say multiple definition error. Actually, it's detected by the linker, not the compiler. At compile time, there's only one definition. You don't have multiple definitions until it's time for multiple translation units to be linked together. If your compiler automatically invokes the linker, it can be difficult to notice the distinction. You can avoid that problem by giving them internal linkage. However, many compilers (quite rightly) give you warnings if you declare a function with internal linkage, but don't actually use it anywhere in the same translation unit. That's because it's the only translation unit where such a function could be used. ... >> Finally, loose all those superfluous semicolons! > For detecting language changes, at least. Which language changes are you thinking of? A semicolon after a function definition has always been superfluous, even back in C. |
"James R. Kuyper" <jameskuyper@verizon.net>: Feb 14 10:20AM -0500 > On Wednesday, February 14, 2018 at 9:50:37 PM UTC+8, James R. Kuyper wrote: >> On 02/13/2018 10:05 PM, wij@totalbb.net.tw wrote: ... >> function or variable with external linkage shall have the same address >> in all translation units. ..." (10.1.6p6). > How unfortunate! Why do you consider that unfortunate? |
Paavo Helde <myfirstname@osa.pri.ee>: Feb 14 10:45PM +0200 >> You will also hit ambiguity problems with calls like "pow10(2);" or >> passing anything that isn't a floating point type. > Is'nt that ambiguity problem for all kind of function overloads? No, if you provide enough overloads, or better yet, a template to take care of any new primitive types added in the future: namespace Ns { inline float pow10(float v) { return ::pow10f(v); }; template<typename T> double pow10(T v) { return ::pow10(v); }; inline long double pow10(long double v) { return ::pow10l(v); }; } |
Paavo Helde <myfirstname@osa.pri.ee>: Feb 14 11:02PM +0200 >>> inline double pow10(double v) { return ::pow10(v); }; >>> inline long double pow10(long double v) { return ::pow10l(v); }; >>> }; In addition, be warned that adding a function in a namespace with the same name as a function in the global namespace is not a good idea, especially if it takes the same number of arguments. Yes, you can make that work, but it's still error-prone and you will lose some extra hair because of this in the future ;-) |
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page. To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com. |
No comments:
Post a Comment