"Alf P. Steinbach" <alf.p.steinbach@gmail.com>: Feb 04 10:32PM +0100 I finally encountered a use for `const T` as function return type. This code appears to work well for the single purpose it's been used for, but it's not tested or even used extensively. And that includes that I haven't even tested/used that `const T` return function yet. But: template< class Item > class Shared_queue_ { queue<Item> m_queue; mutable mutex m_mutex; mutable condition_variable m_condition; auto length() const -> int { return int_size_of( m_queue ); } auto is_empty() const -> bool { return m_queue.empty(); } public: class Access: public Movable { friend class Shared_queue_; Shared_queue_* m_p_queue; Mutex_lock m_mutex_lock; Access( Shared_queue_& q ): m_p_queue( &q ), m_mutex_lock( q.m_mutex ) {} Access( const Shared_queue_& q ): m_p_queue( &q ), m_mutex_lock( q.m_mutex ) {} public: auto length() const -> int { return m_p_queue->length(); } auto is_empty() const -> bool { return m_p_queue->is_empty(); } void wait_for_items() { if( not is_empty() ) { return; } m_p_queue->m_condition.wait( m_mutex_lock, [&]() -> bool { return not is_empty(); } ); } auto wait_for_items_for( const Duration duration ) -> bool { if( not is_empty() ) { return true; } // TODO: handle possible overflow in `steady_clock::now() + duration`. const bool timed_out = not m_p_queue->m_condition.wait_for( m_mutex_lock, duration, [&]() -> bool { return not is_empty(); } ); return not timed_out; } void enq( Item item, const bool notify = true ) { m_p_queue->m_queue.push( move( item ) ); if( notify ) { m_p_queue->m_condition.notify_one(); } } auto deq() -> Item { wait_for_items(); hopefully( not is_empty() ) or FSM_FAIL( "Waited for items but got none; queue is empty." ); return popped_front_of( m_p_queue->m_queue ); } }; auto access() -> Access { return Access( *this ); } auto access() const -> const Access { return Access( *this ); } }; - Alf |
Muttley@dastardlyhq.com: Feb 04 03:30PM Can anyone explain the "official" explanation from whichever standard as to why the first assignment only compiles in C++ but not C: #include <stdio.h> int main() { int a = 0; int b = 0; int x = 0; int y = 1; int c = 123; /* Compiles in C++, not C (x == y ? a : b) = c; */ /* C version */ *(x == y ? &a : &b) = c; printf("a = %d, b = %d\n",a,b); return 0; } Just curious. |
Richard Damon <Richard@Damon-Family.org>: Feb 04 11:04AM -0500 > return 0; > } > Just curious. The key difference is that in C, the results of the conditional operator is always an r-value, and thus not suitable for an assignment operator. By using the address-of and deference operatiors you convert that r-value into an l-value so can make the assignment. In C++, because it has a "reference" type, if the last two terms of the conditional operator are objects of a compatible type, then the type of the result can be a reference to that type, an option not available in C, and this allows its value to be an l-value. |
Muttley@dastardlyhq.com: Feb 04 04:59PM On Sat, 4 Feb 2023 11:04:12 -0500 >conditional operator are objects of a compatible type, then the type of >the result can be a reference to that type, an option not available in >C, and this allows its value to be an l-value. Ok, that makes sense. Though I wonder - given the main C compilers used now are also C++ compilers - why they don't just silently allow it in C? Would there be any wierd or unfortunate side effects in C if it was? |
Richard Damon <Richard@Damon-Family.org>: Feb 04 01:02PM -0500 > Ok, that makes sense. Though I wonder - given the main C compilers used now > are also C++ compilers - why they don't just silently allow it in C? Would > there be any wierd or unfortunate side effects in C if it was? Mostly because in C it is a Required Diagnostic, so to allow it they need to at least issue a warning, so it can't be "silent" without something to at least implicitly define you don't want conformance. Also, basically it goes down to the differing type inference rules of the two langauges, so it would need some explicit code injected into the C parsing part of the compiler. While I can't think of any specific "harm" that allowing it in C as an extention would cause, since it is always a full error in C, I;m not sure that adding it would add that much value as an extenuation since it makes the code needlessly unportable, since the C version isn't that more complicated. |
Bonita Montero <Bonita.Montero@gmail.com>: Feb 04 07:41PM +0100 > (x == y ? a : b) = c; I'm sometimes writing code like this and I love it. If you use it regulary this becomes more readbale than the if'd code. |
Keith Thompson <Keith.S.Thompson+u@gmail.com>: Feb 04 12:45PM -0800 Muttley@dastardlyhq.com writes: [...] > Ok, that makes sense. Though I wonder - given the main C compilers used now > are also C++ compilers - why they don't just silently allow it in C? Would > there be any wierd or unfortunate side effects in C if it was? No, most C compilers are not also C++ compilers. gcc and g++, for example, are part of the same project, but the front ends (where conditional expressions are handled) are separate. For example, I've never seen a grammar that conditionally treats "class" as a keyword depending on the language being processed, and I'd be surprised to see a compiler that uses that approach. A C compiler could support treating conditional expressions as lvalues as an extension (which would be non-conforming if it didn't produce a diagnostic message), and it might be implemented by borrowing code from the corresponding C++ front end, but I wouldn't expect the same code to handle conditional expressions in C and C++ compilers. -- Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com Working, but not speaking, for XCOM Labs void Void(void) { Void(); } /* The recursive call of the void */ |
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