Originally Posted by
zacs7
... How is being Garbage collected or aimed at systems programming asking to fail? You like to do a lot of stirring when you obviously have no clue.
I fail to see how it could work. Those embedded systems with a few KB of ram? Which the garbage collector would sit eating all the time?
And then the problem of deterministic construction. Not saying such a thing isn't possible with GC, but it sure would made it a whole lot harder.
Locking pointers... Barking instructions at the GC...
I don't see how it's beneficial for embedded systems.
Originally Posted by
Mad_guy
Basically just get rid of the C preprocessor in favor of a real module system - you can still reap the benefits of having the specification (i.e. header) separate from the implementation (i.e. module,) but basically not have to deal with all the dumbness of only being able to do essentially textual includes for source code. You actually gain a lot because you can enforce module-level invariants, like certain things are exposed and others are not, and basically all module systems give you the ability to qualify names, so you do not have to namespace everything in order to make sure you aren't going to conflict with things. With hierarchical module structure, you pretty much get all the benefits of namespaces but without the crappiness of CPP. I've mentioned this elsewhere, but the C-preprocessor is the reason the C++ standard library headers look like such complete and total crap, because if you they weren't you could do "#define StrBuf lolitron;" before including iostream - then boom, textual substitution at the preprocessing level causes everything to explode. Hence underscoring things to hell and making them illegible and unreadable. And keep in mind the C++ standard specifies you must do this in order to avoid naming conflicts - Microsoft apparently write their C++ headers using an actually readable style, before running them through a name/identifier obfuscator on their side, the resulting files which they ship to developers for the Windows SDK (so you basically can't possibly clash names.)
That's interesting. But if you follow the convention that all macros should be UPPER CASE, then there should be no problem, though?
I suspect it's because they want thing not to break if someone breaks it?
Simple example: a vector type which is parametrized by its current length (i.e. the type is something abstractly like 'vector 5 int' meaning "this value is a vector of length 5 containing only ints".) You can then parametrize functions over these vectors and enforce invariants in your code. Example: addition of two vectors of length
n and
m is basically undefined behavior if
n != m, or better put, addition is only defined precisely over two vectors of lengths
n and
m where
n == m. You can express this invariant using the type system when defining a function like addition by saying it can only take two vectors where their types say they have the same length. The result is that if you add a vector of length 4 with a vector of length 5, you actually get a compile-time error because the invariant is enforced through the type system.
I
think this can be done in C++ and if anybody would like to take a stab at it, I'd like to see the code, even if the result is only a trivially usable vector type! (and I'll respond with my own code doing the same thing, only in a much more high level language to show a contrast in type system expressiveness.) The result almost always results in the usage of Peano numbers at the type level, so if anybody would like to take a stab at it that's a good starting point.
Ah, I get what you mean. But what you are trying to do is impossible. A vector is a dynamic containers. That is, its size can change at runtime. So there would be absolutely impossible for us to know the size of it at compile time. But we could use an assert:
assert(v1.size() == v2.size());
It's better than nothing.
Now, there are actually 3 solutions to this problem without using vectors.
The first is with standard C arrays:
Code:
template<typename T, int N1, int N2> void AddVec(T (&Vec1)[N1], T (&Vec2)[N2])
{
static_assert(N1 == N2);
}
The second is using std::array variant 1:
Code:
template<typename T, int N1, int N2> void AddVec(std::array<T, N1>& Vec1, std::array<T, N2>& Vec2)
{
static_assert(N1 == N2);
}
And the third is using std::array variant 2:
Code:
template<typename T> void AddVec(T & Vec1, T & Vec2)
{
static_assert(Vec1.size == Vec2.size);
}