- Can one initialise std::string with pre-allocated memory? - 8 Updates
- "The C++ committee has taken off its ball and chain" - 9 Updates
- Is using an address of a declared but not defined function as template argument valid? - 4 Updates
- Implicit conversion error with conversion operator - 1 Update
- Long identifiers, poor readability - 2 Updates
- alignment and endian issues - 1 Update
boltar@cylonHQ.com: Apr 23 08:32AM On Fri, 20 Apr 2018 11:35:02 -0700 (PDT) >I did a post at std-discussion: >Constructor std::string(char * &&). Why not? >https://groups.google.com/a/isocpp.org/forum/#!topic/std-discussion/8_xudInYUkk Interesting code. I'm not sure what the respondent meant by the string doesn't type-erase the memory deallocation operation. The type will always be a char so I don't see why that should be an issue. |
Bo Persson <bop@gmb.dk>: Apr 23 11:54AM +0200 > Interesting code. I'm not sure what the respondent meant by the string doesn't > type-erase the memory deallocation operation. The type will always be a char > so I don't see why that should be an issue. The issue is that the allocator is part of the std::string type. So it calls std::allocator<char>::deallocate to release the memory. Not delete, or delete[], or free, or whatever else might be needed. And if you try some other allocator, you get std::string<char, special_allocator> which is a different type not compatible with the normal std::string. Bo Persson |
boltar@cylonHQ.com: Apr 23 10:24AM On Mon, 23 Apr 2018 11:54:09 +0200 >The issue is that the allocator is part of the std::string type. So it >calls std::allocator<char>::deallocate to release the memory. Not >delete, or delete[], or free, or whatever else might be needed. But if constructed with a pointer it could just set a flag so it would know to use delete or free(). Its not rocket science. |
Bo Persson <bop@gmb.dk>: Apr 23 03:45PM +0200 >> delete, or delete[], or free, or whatever else might be needed. > But if constructed with a pointer it could just set a flag so it would know > to use delete or free(). Its not rocket science. It could, but that requires extra storage and additional tests in the code. And not only for deleting the buffer, but also when moving, swapping, assigning, reallocating, etc. How much extra work do we accept for everything else, to be able to occationally import an existing buffer? Is it a net win for everybody? Bo Persson |
boltar@cylonHQ.com: Apr 23 01:47PM On Mon, 23 Apr 2018 15:45:01 +0200 >swapping, assigning, reallocating, etc. >How much extra work do we accept for everything else, to be able to >occationally import an existing buffer? Is it a net win for everybody? Fair point. |
legalize+jeeves@mail.xmission.com (Richard): Apr 23 04:16PM [Please do not mail me a copy of your followup] boltar@cylonHQ.com spake the secret code >>then use &str[0]. It returns pointer to mutable data unless str was >And this ugly hack is guaranteed to work for every implemetation of std::string >is it? Yes, or use str.data() in C++17 or later. (Prior to C++17, data() returned pointer to const char.) -- "The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline> The Terminals Wiki <http://terminals-wiki.org> The Computer Graphics Museum <http://computergraphicsmuseum.org> Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com> |
legalize+jeeves@mail.xmission.com (Richard): Apr 23 04:17PM [Please do not mail me a copy of your followup] boltar@cylonHQ.com spake the secret code >>> std::string is it? >>You call that "ugly hack" after accusing others of suggesting to casting >It is an ugly hack. "hack" implies that it is not officially supported behavior. This is not true. std::vector<char> f; f.push_back('x'); char *x = &f[0]; and ditto for std::string, has been valid semantics and syntax since C++98. -- "The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline> The Terminals Wiki <http://terminals-wiki.org> The Computer Graphics Museum <http://computergraphicsmuseum.org> Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com> |
jameskuyper@verizon.net: Apr 23 10:29AM -0700 On Monday, April 23, 2018 at 12:17:52 PM UTC-4, Richard wrote: > char *x = &f[0]; > and ditto for std::string, has been valid semantics and syntax since > C++98. Can you cite text from the standard allowing x to be used to access the other elements of the string? I'm not saying that there's no relevant text - but I haven't been able to find it. std::basic_string<> (24.3.2.p3) and std::array<> (27.4.7.1p1) are required to be contiguous containers (26.2.1p13) which means that their iterator types must qualify as contiguous iterators (27.2.1p6), and 27.9.2.4p3 imposes similar requirements on std::valarray<> - but those are the only standard containers for which that is true - std::vector<> has no such requirement. Even for a contiguous container such as std::basic_string<>, you need to use addressof(), not &, to obtain a pointer value for which the requirements of 27.2.1p6 apply. |
Juha Nieminen <nospam@thanks.invalid>: Apr 23 06:30AM > They have done this before, this is nothing new. "auto" and ">>" are the > first examples of considered *and* accepted changes which pop to mind. In what way has the operator >> changed in such a manner that has made old code not compile? |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Apr 23 10:12AM +0200 On 23.04.2018 08:30, Juha Nieminen wrote: >> first examples of considered *and* accepted changes which pop to mind. > In what way has the operator >> changed in such a manner that has made > old code not compile? It's about template argument lists, like foo<bar<41>> In C++03 you had to write foo<bar<41> > Cheers & hth., - Alf |
Juha Nieminen <nospam@thanks.invalid>: Apr 23 09:45AM > foo<bar<41>> > In C++03 you had to write > foo<bar<41> > The question was about code that *stopped* compiling due to the change in standard, not code that previously didn't compile but now does. |
Ben Bacarisse <ben.usenet@bsb.me.uk>: Apr 23 11:03AM +0100 >> foo<bar<41> > > The question was about code that *stopped* compiling due to the change > in standard, not code that previously didn't compile but now does. So flip the problem round: template <int n> struct A { int a[n]; }; ... A< n>>1 > x; became a syntax error with C++11. -- Ben. |
Chris Ahlstrom <OFeem1987@teleworm.us>: Apr 23 07:38AM -0400 Jorgen Grahn wrote this copyrighted missive and expects royalties: > Personally I like conservative languages, like C++. "Exciting new > features" don't excite me -- or I'd be cargo-culting the > JVM-language-of-the-week instead. +1 -- Q: What's tan and black and looks great on a lawyer? A: A doberman. |
legalize+jeeves@mail.xmission.com (Richard): Apr 23 04:14PM [Please do not mail me a copy of your followup] Ben Bacarisse <ben.usenet@bsb.me.uk> spake the secret code > ... > A< n>>1 > x; >became a syntax error with C++11. The workaround is to use A<(n >> 1)> x; -- "The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline> The Terminals Wiki <http://terminals-wiki.org> The Computer Graphics Museum <http://computergraphicsmuseum.org> Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com> |
Lynn McGuire <lynnmcguire5@gmail.com>: Apr 23 11:43AM -0500 On 4/19/2018 4:03 AM, Jorgen Grahn wrote: > features" don't excite me -- or I'd be cargo-culting the > JVM-language-of-the-week instead. > /Jorgen Because I want to convert my calculation engine from F77 to C++. I need all the speed that I can get as we are still computationally intensive and threading our calculation engine is a no-go. Thanks, Lynn |
Ben Bacarisse <ben.usenet@bsb.me.uk>: Apr 23 05:52PM +0100 >> A< n>>1 > x; >>became a syntax error with C++11. > The workaround is to use A<(n >> 1)> x; Yes, but not really the point! -- Ben. |
legalize+jeeves@mail.xmission.com (Richard): Apr 23 05:02PM [Please do not mail me a copy of your followup] Lynn McGuire <lynnmcguire5@gmail.com> spake the secret code >Because I want to convert my calculation engine from F77 to C++. I need >all the speed that I can get as we are still computationally intensive >and threading our calculation engine is a no-go. If your code has intrinsic data parallelism, you might want to consider CUDA for the GPU. -- "The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline> The Terminals Wiki <http://terminals-wiki.org> The Computer Graphics Museum <http://computergraphicsmuseum.org> Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com> |
kmo <this@e.mail.invalid.is>: Apr 23 12:11PM Please consider the following code: CODE START---------------------------------------- #include<stdio.h> int f1(int, int); int f2(int, int); int f3(int); template<typename T, T *ptr> inline void *fid() { return (void *)&fid<T, ptr>; }; int main() { printf("%p\n", fid<decltype(f1), f1>()); printf("%p\n", fid<decltype(f2), f2>()); printf("%p\n", fid<decltype(f3), f3>()); return 0; }; CODE END------------------------------------------ fid takes a function pointer as template parameter and returns the pointer to itself, making a kind of numeric identifer of a declaration. This is the entire source code, no additonal files are present. f1, f2, f3 are only delcared here, no definition is given. The question is: a) is this code valid (should this code compile)? b) if it is, what should it output: are three different pointers guaranteed? c) if it is not, why? Or, maybe, it is a some case of undefined behavior / no diagnostics required? My reasoning goes this way: Main question: Are f1, f2, f3 ODR used? If yes, the code sould not compile. If not, fid instances are different objects, so they should have different addresses. Visual Studio 2017 (15.6.6) compiles and prints 3 equal pointers, unless you compile it with /GL (whole program optimization) in which case linker complains about unresolved f1, f2, f3. However, replacing every fid<decltype(f*), f*> with fid<decltype(f*), &f*> for *=1,2,3 silences the linker and the output is 3 equal pointers. Clang (bundled with the mentioned Visual Studio, LLVM-2014) also compiles, prints 3 different pointers. Compiling in Release produces 3 equal pointers. g++ 4.8.1 (MinGW) compiles and prints 3 different pointers. g++ 5.2.1 (Ubuntu 15.10) compiles, 3 different pointers. clang++ 3.6.2 (Ubuntu 15.10) compiles, 3 different pointers. Compilers on Compiler Explorer compile it just fine, but probably the code is only compiled, not linked (G++ 7.3, ICC 18.0.0, CLang 6.0.0, MSVC 19 2017 RTW). So the majority says a) yes, b) different, but is the majority correct? |
"James R. Kuyper" <jameskuyper@verizon.net>: Apr 23 09:30AM -0400 On 04/23/2018 08:11 AM, kmo wrote: > }; > int main() { > printf("%p\n", fid<decltype(f1), f1>()); Note 1: "%p" requires a void* argument. On many systems, all pointers are interchangeable, so it doesn't matter, but the C++ standard doesn't require this. Note 2: 7.11p2 defines the conversion from a pointer to an object type to a void*. There's no corresponding clause describing conversion from a pointer to a function type to a void*, except 7.11p1, which only applies to null pointers. The behavior of converting a non-null pointer to a function to void* so it can be used by printf("%p") is therefore undefined by omission of an explicit definition (3.27). The best you can do with function pointer is to store in in an pointer object, and then print a hex dump of the bytes that make up the pointer. In practice, such code has good chance of working as you expect it to, particularly if you're using a POSIX-compliant system: dlsym() can only work as it's supposed to if the function pointers it works with can be safely converted to and from void*. That doesn't guarantee that any other function pointers can be safely converted, but it does make it more likely. > Or, maybe, it is a some case of undefined behavior / no diagnostics required? > My reasoning goes this way: > Main question: Are f1, f2, f3 ODR used? "A function whose name appears as a potentially-evaluated expression is odr-used if it is the unique lookup result or the selected member of a set of overloaded functions (6.4, 16.3, 16.4), unless it is a pure virtual function and either its name is not explicitly qualified or the expression forms a pointer to member (8.3.1)." f1, f2, and f3 are the unique lookup results, so that clause should apply - there are no overloaded or pure virtual functions involved, so none of the exceptions apply. > If yes, the code sould not compile. I think it should compile - but what it should not do is link. |
Bo Persson <bop@gmb.dk>: Apr 23 03:35PM +0200 On 2018-04-23 14:11, kmo wrote: > Compilers on Compiler Explorer compile it just fine, but probably the code > is only compiled, not linked (G++ 7.3, ICC 18.0.0, CLang 6.0.0, MSVC 19 2017 RTW). > So the majority says a) yes, b) different, but is the majority correct? MSVC is known to merge functions with identical machine code. This helps remove redundant template expansions, but also accidentally produces the same address for different (but very similar) functions. Bo Persson |
"Öö Tiib" <ootiib@hot.ee>: Apr 23 06:54AM -0700 On Monday, 23 April 2018 15:11:37 UTC+3, kmo wrote: > a) is this code valid (should this code compile)? > b) if it is, what should it output: are three different pointers guaranteed? > c) if it is not, why? Seems that it is not valid code and so may refuse to compile. > Or, maybe, it is a some case of undefined behavior / no diagnostics required? > My reasoning goes this way: > Main question: Are f1, f2, f3 ODR used? Yes, these have to be selected by overload resolution when addresses are taken so must be ODR-used. > If yes, the code sould not compile. > If not, fid instances are different objects, so they should have different > addresses. Perhaps the reason why it compiles is that the usage of those function pointers taken is optimized out so linker (unless it is whole program optimizer) has no usages left to link to. > Compilers on Compiler Explorer compile it just fine, but probably the code > is only compiled, not linked (G++ 7.3, ICC 18.0.0, CLang 6.0.0, MSVC 19 2017 RTW). > So the majority says a) yes, b) different, but is the majority correct? I think the compilers are incorrect, but I can't imagine an actual problem, some motivating example that their incorrectness would break for me. |
Juha Nieminen <nospam@thanks.invalid>: Apr 23 09:58AM Consider the following code: //------------------------------------------------------------ struct Coords { int x, y; }; struct Foo { Foo(Coords); }; struct Bar { operator Coords() const; }; const Foo foo = Bar(); //------------------------------------------------------------ When I try to compile it with (a recent version of) clang, I get the error: ---------------------------------------------------------------------- error: no viable conversion from 'Bar' to 'const Foo' const Foo foo = Bar(); candidate constructor not viable: no known conversion from 'Bar' to 'Coords' for 1st argument Foo(Coords); candidate function operator Coords() const; ---------------------------------------------------------------------- It's giving the operator Coords() function as a candidate function, but doesn't explain why it's rejecting it. |
Jorgen Grahn <grahn+nntp@snipabacken.se>: Apr 23 05:29AM On Fri, 2018-04-20, Ian Collins wrote: > namespace tcp = boost::asio::ip::tcp; > std::function<void(tcp::socket&&)> server; > Would help. IIRC, there are also other long incantations like this in boost::asio, so he may have to do a few of those. > boost::asio is a pathological case for nested namespaces! Yes. It's unclear to me if the OP has problems specifically with boost::asio (understandable!) or also with more normal examples of namespaces. /Jorgen -- // Jorgen Grahn <grahn@ Oo o. . . \X/ snipabacken.se> O o . |
Juha Nieminen <nospam@thanks.invalid>: Apr 23 06:34AM > socket.async_write_some(boost::asio::buffer(output.buf + output.len, n), > [ptr](boost::system::error_code const& ec, std::size_t n) { > feels rather hard to read. I actually find those easier to understand because the names are very self-documenting. They are telling me what those names 'function', 'socket', 'buffer', and 'error_code' are (or, more precisely, which library they belong to, and where to look for their documentation if I don't know what they do.) If you had written, for instance, "buffer(output.buf + output.len, n)", I wouldn't even know that it's a Boost function. It could be anything. It might not even become apparent with the whole source file. |
Juha Nieminen <nospam@thanks.invalid>: Apr 23 06:25AM > OK and C++ standard says not OK. But C++'s words implies nearly all > kinds of CPU. In my cases, I just worry about CPU that can address say > 2-Gbytes of space, and see if there is chance is_valid2(..) can work. Btw, if you want a concrete example where the program will crash because of reading a word breaking alignment boundaries, the UltraSparc processor is such an example. (It's actually very common in RISC processors, as they tend to have simplified memory access for efficiency, and will not have specialized logic to read words across alignment boundaries, and will simply trigger an interrupt if that's attempted.) |
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