Skip to content

Instantly share code, notes, and snippets.

@easyaspi314
Last active February 25, 2019 08:03
Show Gist options
  • Save easyaspi314/cb397a285a2db7cfe32f2fac4d7c0f06 to your computer and use it in GitHub Desktop.
Save easyaspi314/cb397a285a2db7cfe32f2fac4d7c0f06 to your computer and use it in GitHub Desktop.
C+: Another Better C

C+: Another Better C

C+ is like halfway between C11 and C++.

Unlike C++, C+ remains a procedural language, and some things are intentionally left out.

Here are some potential ideas.

First, what will be removed:

  • Traditional prototypes and declarations. ANSI only.
  • No given arguments = no specified arguments
  • Implicit int
  • auto keyword
  • Implicit declarations
  • Nested qualifier rule (void ** can implicitly convert to const void **)
  • VLAs. They are terrible. Flexible struct members are fine.
  • Implicit pointer conversions. It is an error now. Sorry.
  • String literals are always const char *.

Additions from C++

  • 'x' is char. Not int. This makes generics much easier.
  • lvalue references. A syntax sugar that makes code much more readable.
  • Namespaces
  • enum struct
  • The generic container and string libraries from the STL.
  • Smart pointers.
  • auto
  • Operator overloads for user types?
  • cout and cin: put and get:
put("Hello", "World", "\n");
get(&c);
  • std::function: _Func(int(void)) *fptr
  • __has_include, feature test macros
  • Attributes

Additions from other extensions

  • typeof
  • ({ statement; expressions; })
  • Inline assembly
  • #pragma push_macro
  • case 1..4:
  • void foo(int ptr[static size_t size]) will automatically pass the size of ptr if the argument is not specified and the size can be determined. It also follows the rules of static bounds checking.

Completely new stuff

  • Macros are smarter.
    • Putting parentheses in macro arguments will surround all instances with parentheses unless preprocessor operators are used on them.
    • __VA_OPT__, ##__VA_ARGS__, __VA_COUNT__, and __VA_APPLY__(expr)
    • Expansion is easier, no need to double expand.
    • A new _Mangle keyword which merges all contents into a valid unique identifier: _Mangle(foo const char * "Hello" 'a' 4 [3]) -> foo_const_char_P_Hello_a_4_Ar3
    • _Generic only type-checks matching expressions. This means that you don't need to worry about explicit casts and stuff.
    • String literals can be parsed by the preprocessor.
  • Anonymous, non-typedef'd structs are duck typed. If they match, it is the same type.
  • restrict typedef: A restrict typedef means that said typedef cannot be converted to its base type without a cast.
  • In addition, there are smarter "safe" functions. The only thing they do is they follow logic. They have automatic bounds checking and they don't do stupid things like not null terminating a string.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment