• Advertisement


  • Content count

  • Joined

  • Last visited

Community Reputation

123 Neutral

About yacwroy

  • Rank
  1. Ok thanks for pointing me in the right direction re the standard. This might be from a later version of the draft (C++ std version N3126): Quote:§12.8.17 --4 an array is initialized by moving each element in the manner appropriate to the element type; That seems fairly explicit. I submitted a bug to GCC.
  2. Is this intended? #include <iostream> struct CFoo { CFoo() =default; CFoo(const CFoo&) { std::cout << "copy" << std::endl; } CFoo(CFoo&&) { std::cout << "move" << std::endl; } }; struct CBar { CBar() =default; CBar(const CBar&) =default; CBar(CBar&&) =default; CFoo foo[2]; CFoo f; }; int main() { CBar b = std::move(CBar()); }; Output: copy copy move (Compiled with GCC 4.6) Shouldn't the foo[] array members be moved, just like the regular member? or is this correct? I have a workaround if it's correct, but it just seems kind-of inconsistent. Thanks.
  3. Overriding new

    If you still need help: Does my code compile OK for you? It compiles fine as-is in gcc here. If not, your compiler likely has issues. If so, slowly change my code back into yours until it breaks. I only merged it all into one file, added const to char (which it needs as __FILE__ is of type const char*), removed the "operator new" function body and replaced it with a dummy, added the #include <new> which you had elsewhere and added the main() function.
  4. Overriding new

    #include <new> extern void* operator new(size_t size, const char* file, int line); #define MY_NEW new(__FILE__, __LINE__) void* operator new(size_t size, const char* file, int line) { return (void*)1; } struct MyObject {}; main() { MyObject* p = MY_NEW MyObject(); } Works fine here. Did you #include <new>? Your char* should be const char*. You don't need the extern (but this shows it causes no problems). Your new doesn't have a return statement. I stripped the definition of new but this isn't relevant to fixing your error.
  5. I'm wanting to write a routine that I can use from within an interrupt callback to add a task to a threadpool. The threadpool's add task code is mutex-protected. The tasks can potentially run third-party code so I don't want to place any time constraints on them, which is why I want to run them from the threadpool. The interrupt callbacks can potentially come from any interrupt source. The most likely candidates are system timers and input device APIs. If I understand correctly: Interrupt callbacks may have disabled interrupts. Multiple interrupt callbacks can potentially run concurrently, even from the same device. If I simply call the threadpool's add task from the callback, I'm wondering if this could occur: 1. Device 1 generates interrupt. 2. Handler 1 calls my_callback. 3. my_callback locks threadpool.lock. 4. Device 2 generates interrupt. 5. Handler 2 disables interrupts. 6. Handler 2 calls my_callback. 7. my_callback fails to lock threadpool.lock and tries to wait. 8. deadlock with interrupts disabled. Is this possible, or is there some mechanism I don't know of that prevents this. I'm looking for a threadsafe deadlock-safe version. I'm ultimately looking for a cross-platform solution, (or solutions for Linux, Win and Mac). But for now I'll settle for a Linux-only solution. I thought of a lock-less circular queue, but there's potentially multiple writers to the queue which could cause race conditions (eg, interrupts might be forgotten). Another solution is to use an array of mutexes, and to use non-locking mutex attempts on them consecutively, assuming that it's highly unlikely all of the mutexes will be locked. But that's pretty untidy and inefficient. Am I getting worked up over nothing or is this actually as hard as it seems? Thanks.
  6. I have another solution: just add an extra layer of indirection (ie: pointer to pointer). #include <iostream> class CFoo {}; class CBar : public CFoo {}; CBar bar; extern CFoo* const bar_ptr; CFoo* const bar_ptr = &bar; template <CFoo* const* rPTR> void zug() { std::cout << (*rPTR) << std::endl; std::cout << &bar << std::endl; } int main() { zug<&bar_ptr>(); } Output: 0x601180 0x601180 Quote:Original post by AntheusThe reason compiler barfs on this is that location, or even existence of bar is determined by the linker - compiler only emits a symbol, and template expansion is completed before then. I'm pretty sure that template expansion is allowed to complete even if the pointer is only an unresolved symbol. At least, that's what seems to be happening. Anywhere the pointer is used in the template the object code will still have the symbol in it. Quote:Original post by Sudi Nevermind.... try this approach. That's the backup plan if I can't get this fixed and decide not to use the above method. BTW, here's the offending bit of standard (Thanks to SiCrane). Bold-ing is mine.: Quote:Original post by C++ International Standard 2008. 14.3.2 para 5 item 2for a non-type template-parameter of type pointer to object, qualification conversions (4.4) and the array-to-pointer conversion (4.2) are applied; if the template-argument is of type std::nullptr_t, the null pointer conversion (4.10) is applied. [ Note: In particular, neither the null pointer conversion for a zero-valued integral constant expression (4.10) nor the derived-to-base conversion (4.10) are applied. Although 0 is a valid template-argument for a non-type template-parameter of integral type, it is not a valid template-argument for a non-type template-parameter of pointer type. However, both (int*)0 and nullptr are valid template-arguments for a non-type template-parameter of type “pointer to int.” — end note ] So, if I read that right, it seems it doesn't work simply because someone specifically excluded it. Perhaps there could be some issue with using it that I/we haven't thought of.
  7. Quote:What are you really trying to do? And why? I'm resurrecting an old project of an allocator library. I'm just working on making the interface tidier. The library guarantees a minimum space efficiency (committed memory is kept under 2*(requested memory) + ~10MB), yet allocation operations are O(ln N) so there aren't any freezes due to compacting memory. To do this the allocator must be given autonomy and allowed to move allocated chunks at will, so the chunks contain a pointer to a move function that keeps links etc intact after moving. Due to this extra type-specific information requirement, I can't just overload new and delete. I have an allocator object class that provides the alloc() and dealloc() calls. Like STL I want to allow the use of multiple allocators (here, two can operate safely in different threads without blocking eachother). STL uses an allocator trait class as a (defaulted) template parameter in classes such as std::vector. But I think it'd be nicer to use vector<&allocator_pointer> than vector<trait_class> as you avoid having to write trait_class. All works well for a single type of allocator class. However, I now want to make my allocator class abstract, mainly because there can be different patterns of allocation that can be modeled in different ways. eg: class CDerivedAllocator : public CAllocator { // ... }; CDerivedAllocator my_allocator; // Now for a class that uses my allocator: template <CAllocator* alloc> class CObject { // ... }; CObject<&my_allocator> object; // <- this is the problem. I hope that makes sense. It's not an insurmountable problem, but it would be an improvement, and I can't see why it's not possible.
  8. Quote:Original post by CmpDev Template parameters are compile time, pointers to instances are run time. The reason the first works it that the type is correct, but the address is not passed to the function and can not be used as is. The following shows zug() using the instance. The pointer to foo is constant, and thus available compile-time. #include <iostream> struct CFoo { void say() { std::cout << this << std::endl; } }; struct CBar : public CFoo {}; template <CFoo* P> void zug() { P->say(); } CFoo foo; int main() { zug<&foo>(); std::cout << "foo @ " << &foo << std::endl; } Compiles fine and outputs: 0x601180 foo @ 0x601180 In the original example, bar's address is also available at compile time. bar is a CBar, and CBar is derived from CFoo, so bar is a CFoo. &bar is a CFoo* and is available at compile-time (just like &foo). Yet &foo works and &bar doesn't.
  9. I have a template function (zug) that takes a pointer to a CFoo as its parameter. I have a global variable (bar) whose type (CBar) is derived from CFoo. Is it possible to invoke zug() with bar's address as the template parameter? I can't see any reason why not, but every method I try seems to fail. struct CFoo {}; struct CBar : public CFoo {}; template <CFoo* P> void zug() {} CFoo foo; CBar bar; CFoo& bar_as_foo(bar); CFoo* const bar_foo_ptr = &bar; const CFoo* const c_bar_foo_ptr = &bar; int main() { zug<&foo>(); // Works fine. zug<&bar>(); // 1. G++: error: no matching function for call to 'zug()' zug<(CFoo*)(&bar)>(); // 2. G++: error: 'bar' cannot appear in a constant-expression. etc.. zug<&bar_as_foo>(); // 3. G++: error: no matching function for call to 'zug()' zug<bar_foo_ptr>(); // 4. G++: error: 'bar_foo_ptr' cannot appear in a constant-expression zug<c_bar_foo_ptr>(); // 5. G++: error: 'c_bar_foo_ptr' cannot appear in a constant-expression. zug<(CFoo*)(&bar_as_foo)>(); // 6. G++: error: 'bar_as_foo' cannot appear in a constant-expression. etc... zug<bar>(); // 7. G++: error: 'bar' is not a valid template argument because 'bar' is a variable, not the address of a variable zug<&((CFoo&)bar)>(); // 8. G++: error: parse error in template argument list. ((CFoo&)bar) = foo; // Syntax works here though. } Does anyone know how to do this, or if it's impossible? Thanks. (g++ 4.5.2 / ubuntu 64 bit)
  10. Thanks guys. Surprised I haven't met that one before. Quote:the C++ grammar is way too complex and ambiguous for the parser to not get confusedYou can say that again. Here's hoping concepts will arrive soon and tidy things up a bit.
  11. I have a template struct SFoo. It has a template function bar() which takes no parameters. I have a global function zug() and a global template-function qop(). Both functions create an instance "foo" of SFoo. zug() uses int as SFoo's template parameter while qop<T> uses T. I want to call foo.bar<float>() from these functions. template <typename pTYPE1> struct SFoo { template <typename pTYPE2> void bar() {} }; void zug() { SFoo<int> foo; foo.bar<float>(); } template <typename pTYPE1> void qop() { SFoo<pTYPE1> foo; foo.bar<float>(); // Error. } ../test/call_empty_template_func_of_template_struct.cpp: In function 'void qop()': ../test/call_empty_template_func_of_template_struct.cpp:19:13: error: expected primary-expression before 'float' ../test/call_empty_template_func_of_template_struct.cpp:19:13: error: expected ';' before 'float' Since bar takes no parameters, I explicitly provide bar's template argument in the call to bar. This works fine for zug() but, for some reason I can't tell, it fails for qop. If I make bar<X>() take a dummy parameter of type X I can then remove the <float> from the call to bar, and simply pass a dummy float. This works fine (tested) but is wasteful & ugly. But why can't I just call foo.bar<float>()? Shouldn't this work fine? Compiler: g++: ([4.3.3] & []) OS: ubuntu: 9.04 64 bit.
  12. Quote:Please write N prefixes on your nouns. It tells me they're nouns (words that are ordinarily nouns can sometimes be used as adjectives or verbs), reduces name collisions, and is easier for me to read. Please write "s" suffixes on your plurals. It tells me they're plurals (as sometimes the context doesn't imply this), it's easier for me to read. I'm sorry, but English has modifiers like these all over the place. They aid comprehension. "I am eat my bag of grape." is understandable, but modifiers make it easier to read. Like C++. there are places where the lack of these modifiers may prevent full comprehension in sections of text. I have no issue with you not using prefixes. Yet I and many others find prefixes make code easier to read. You may not, but don't assume that everyone else is like you. Brains aren't all built the same. The authors of C and C++ deliberately did not add style requirements. The C++ standards committee has not expressed any intention to add them. BTW Zahlman, did you mod me down for disagreeing with you?
  13. Edit: wrote this before many replies. Visitor, what compiler did you use? Did anyone else manage to compile / fail to compile this? Sorry I don't have other compilers on hand and I'm trying to see whether I need to submit another bug report. I think I'll ask for bug confirmation the GCC mailinglist. Beats submitting a false bug report. Quote:However, a default copy ctor and assignment operator will, in C++, automatically copy array elements element by element.Yes. Strangely, the default assignment op works fine if it's not explicitly declared as default. Quote:Now, I'm not too familiar with C++0x, so I don't know if they changed that, but I'm guessing not.I've read the proposed changes and I'm pretty sure there's no mention of this. There's actually an article somewhere describing the few c++0x backwards-compatibility breakers and I'm sure this wasn't mentioned. Now back to the old style arguments, what fun :) Quote:Any other information is easily obtained with any decent IDE by just hovering over the identifier.Not everyone browses code in a IDE all the time. For example: View source online (where you're likely to not know what many things are) and you get no highlighting. Other places where syntax highlighting can't occur are Emails/SMS, bug reports, compiler errors. Syntax highlighters aren't infallible either. Have your definition in a header whose path can't be known until compilation and your highlighter has no clue how to highlight. Quote:I don't even have a clue what you meant by 'class syntax sometimes overlaps with...'. I meant that there's examples for each of the above things where an identifier in a code fragment could either be a class or the other thing, and you can't tell without accurate highlighting or knowing the object beforehand which it is. Quote:If you are having such problems with name collisions you should be using namespaces more often.Mostly I agree. There are certain uncommon places where it can occur. For example, I have a class containing a member struct, say SBlob (not the actual name), which can't be namespaced. SBlob blob(...) appears in the code. Can't use blob blob(...). Blob blob would work but it's too similar. I didn't mean to say that I want people to change (I was just inverting Zahlman's post, sorry I should've clarified). I just want people to stop complaining about others' nomenclature and structure. Perception etc is different in every user and thus what is better/easier for one may be worse/harder for others. Plenty of people use prefixing. Plenty don't. There's no consensus. There are good reasons for both. Same goes for methods of indent & brace placement, the length or existence of line character limits etc. Just be consistent.
  14. Quote:You mean return type, maybe? Did you try a return type of CFoo&?Yes. also "const CFoo&" and "CFoo" Quote:(And please, please stop writing 'C' prefixes on class names. It tells you nothing that can ever really be useful and makes your code harder to read.)Please write C prefixes on your classes. It tells me it's a class (class syntax sometimes overlaps with functions, namespaces, variables, enums and more), reduces name collisions, and is easier for me to read. :P.
  15. I'm not sure whether this is another GCC C++0x bug. I have a class containing both an array and a virtual function. If I explicitly define the = operator as default, then call this operator, GCC gives me "invalid array assignment". If I remove either the virtual function or the array it compiles OK. struct CFoo { void operator = (const CFoo&) =default; virtual void nep() {} int bar[1]; }; int main(int argc, char* argv[]) { CFoo a; CFoo b; b = a; } ../test/invalid_array_assign.cpp:2:3: error: invalid array assignment ../test/invalid_array_assign.cpp:2:3: error: return-statement with a value, in function returning 'void' ../test/invalid_array_assign.cpp: In function 'int main(int, char**)': ../test/invalid_array_assign.cpp:16:9: note: synthesized method 'void CFoo::operator=(const CFoo&)' first required here Note: The return value of operator = doesn't seem to affect anything. Details: G++ 4.5.1 Ubuntu 9.04 64-bit. Can anyone see why? Can anyone else confirm this fails with GCC (needs -std=c++0x). Thanks. Simon.
  • Advertisement