Of course this isn't an argument, but this shows that even though C++ doesn't prevent you from falling into the same trap that are present in C, it does give you the tool to at least allow you to do better than C to avoid these traps, notably thanks to RAII.
Oh and let's not forget nullptr, which is a blessing compared to NULL.
Pointers are still a feature of both languages.
Pointers in C++ are basically the same than in C, just with mechanisms that solve the ownership and some safety problems.
So yes, it allows the same holes, but at least you have tools to avoid falling in them.
RAII -> Why? nullptr vs. NULL -> Why? Pointers -> Why? Don't use them in a certain way -> Why?
The answer in all cases is C.
There are endless languages that have pointers, no need to talk anything about C.
Starting to sound like a broken record. No, the answer in all cases can also be found in C++, and understood in C++ terms alone. C++ is a SUPERSET of C, not just an arbitrary language + C.
i will now abstain from further conversation - i will leave you with this - i don't care to read your answer in case i have to respond and you might have to deal with some more repetition:
using the language of sets, the set of C++ minus the set of C, with what is now left:
how can you explain the things i have listed?
As evolution within the same language. Inconsistent ideas ironed out for more uniform and safer handling.
A lot of used languages have similar historical warts...
How do you explain "var" in JS, when "let" exists?
Out function parameters are implicit pointers via references. Cannot be null.
Pointers and arrays aren't compatible.
Pointer arithmetic is frown upon and in many of those languages requires an explicit unsafe block/system module import.
How it allows for all the C pointer features, while adding a little bit more safety.
MODULE examples;
IMPORT Terminal, SYSTEM;
(* procedure with reference parameter, no need for pointers *)
PROCEDURE ChangeParam (VAR changeMe: CARDINAL);
BEGIN
changeMe := 25;
END ChangeParam;
(*
procedure with a slice, bounds given by HIGH(changeMe) and LOW(changeMe).
also a string in this case
no need for explicit pointers
*)
PROCEDURE DumpLetters (VAR letters: ARRAY OF CHAR);
VAR
i : CARDINAL;
BEGIN
FOR i := 0 TO HIGH(letters) DO
WriteChar(letters[i]);
WriteLn;
(* Or just use *)
WriteString (letters);
END DumpLetters;
VAR
anInt : CARDINAL := 12 ;
aPtr : POINTER TO CHAR;
aBuffer : ARRAY [1..2] OF CHAR;
anAddr : ADDRESS; (* think void* *)
aPtr2 : POINTER TO CHAR;
BEGIN
WriteInt(anInt); (* writes 12 *)
ChangeParam (anInt);
WriteInt(anInt); (* writes 25 *)
DumpLetters ('A simple string');
NEW(aPtr); (* The compiler knows the size, no need for sizeof, but you can use ALLOCATE(aPTR, SIZE(CHAR)) if you want *)
(* This is where it shares the same problems with C, due to manual memory control *)
DISPOSE(aPtr);
(* do pointer arithmetic if really required *)
anAddr := SYSTEM.ADDADR (SYSTEM.ADR(aBuffer), SIZE(CHAR) * 1);
aPtr2 := SYSTEM.CAST(POINTER TO CHAR, anAddr); (* aPtr2 now points to aBuffer(2) *)
END examples;
So the compiler will mark this module as unsafe since the meta-package SYSTEM is being used.All Modula-2 successors, have GC support, as such the DISPOSE() would have to be written as SYSTEM.DISPOSE() and could only be applied to untraced pointers.
http://stackoverflow.com/questions/6456253/why-is-reference-...
it's a great shame it's defined in such an alien to use way in C++.