structs do have a default constructor, under exactly the same circumstances that classes do.
By the way, a struct isn't "a class with everything public". It's a class with public as the default access specifier. structs can have private members, but your code reviewer might punch you if they do.
The relevant issue isn't struct vs. class, it's POD vs. non-POD.
Remember how an "int" member of a class is uninitialized unless you give it a value in the initializer list or set a value in the constructor? Well, the same applies to all POD types. The default constructor for a POD struct (or a POD class, for that matter) has nothing to do. So, although it nominally exists, a compiler shouldn't actually generate and call it.
This means that the default constructor for any type that you could have defined in C, should introduce no runtime overhead when used in C++. In practice, I hear rumours that not all C++ compilers apply enough optimisation to ensure that all code always emits a binary as good as it would have done if compiled as C. But I don't know whether this is ever one of the issues causing problems - I'd guess that it's usually identical.
So, given a POD struct:
struct sPOD {
int foo;
float bar;
char baz[23];
};
The following is likely to emit no code in C++ (other than maybe moving the stack pointer, depending how much the compiler rolls automatic variables together), just like in C:
sPOD s1;
Indeed it doesn't for me on gcc.