Originally posted by atomsymbol
View Post
Announcement
Collapse
No announcement yet.
Coroutines & Modules Added For C++20
Collapse
X
-
Originally posted by Ananace View Post
From how I understand modules to work, it is left up to the compiler to pass the necessary information (AST etc) between modules where necessary, instead of being the job of the preprocessor - which just naively inlines the entire header and all its includes.
Skipping the preprocessor here speeds up compiling immensely as you no longer need to parse headers more than once between correctly built modules, but you still get full visibility into the definition, just as an AST or other compiler-friendly datastructure.
Comment
-
Originally posted by bountykiller View Post
In fact you will still need to declare the class/methods you want to export in a specific part of our code (I think they call it the module preambule). The compiler won't compute it for you. So this is still better that the #include model because you won't have the header files textually included in our files, but it won't save you from having the declaration and the implementation defined in different places. (Note that this is a reason why I'm not really excited about modules).
- 1 like
Comment
-
Originally posted by atomsymbol View PostTrue, although the PImpl pattern require the programmer to define an extra class which would be unnecessary in some cases if the language&compiler allowed usage of classes (method calls) without knowledge of field types. Abstract interfaces still require #include directives due to instantiation via operator new of interface implementations, which is unnecessary because the invoking the constructor+operator_new does not need the caller to know the representation of class's fields.
Code:class Interface { public: // factory method for constructing an instance. static Interface *create(); virtual ~Interface() {} virtual void f() = 0; };
Code:class Impl: public Interface { public: void f(); private: // some types from a non-public library dependency can go here }; Interface *Interface::create() { return new Impl(); }
- 2 likes
Comment
-
Originally posted by atomsymbol View Post
The use cases are (class T):- Accessing a T's field directly
- Calling a function/method/constructor/destructor which uses the inline keyword and accesses a T's field
- Instantiating T on the stack - although after some though this still does not require the knowledge of T's fields, just the knowledge of T's size and alignment
- Static variables of type T - although after some though this still does not require the knowledge of T's fields, just the knowledge of T's size and alignment
For template classes, the use cases are still just 1 and 2.
Also, how about:- Deriving from T
- static_cast< DerivedFromT * >( T * )
- Passing T by value
- Invoking T's default constructor, destructor, assignment operator, or copy-constructor?
- sizeof (T)
- new T()
Sure, a lot of these boil down knowing size and alignment, but then we're talking about use cases and not underlying requirements.
- 3 likes
Comment
-
For what I've understood C++ modules are just the next evolutionary step for precompiled headers. Many C++ headers are really slow to parse so now you will get some core stuff as modules. I wouldn't expect them to be generally used in projects at least in near future beyond that scope.
- 1 like
Comment
-
Originally posted by coder View PostIt's odd that you think the size and alignment requirements can be known apart from the other details of a type. Maybe in some imaginary language, but we're talking about actual C++. And while one can compute these in template expressions, you need to start with full visibility of the type. So, all of cases 1-4.
Originally posted by coder View PostAlso, how about:- Deriving from T
- static_cast< DerivedFromT * >( T * )
- Passing T by value
- Invoking T's default constructor, destructor, assignment operator, or copy-constructor?
- sizeof (T)
- new T()
Sure, a lot of these boil down knowing size and alignment, but then we're talking about use cases and not underlying requirements.
Passing T by value: This case can be reduced to allocation of sizeof(T) bytes followed by invocation of the copy-constructor.
Invoking T's default constructor, destructor, assignment operator, or copy-constructor: These are plain function calls, unless inlining. Default constructor/etc are automatically marked as inline by current compilers - a current-compiler-specific feature.
new T(): This is a call to function "T* new_T()" created by the compiler in the single .cc file that can see the field types and thus knows sizeof(T).
Comment
-
Originally posted by atomsymbol View Post[I]C++ forces the programmer to define types of fields of a struct/class before the struct/class is defined. This is putting a very strict constraint on the ordering of struct data types in the source code. You cannot call a virtual method (defined elsewhere !!!) before the struct definition has seen the definition of the types of its fields, while obviously the knowledge of fields is immaterial to the virtual method call.
it is an example of clueless commentator with outrageous claims
- 2 likes
Comment
Comment