[ / / / / / / / / / / / / / ] [ dir / random / 93 / biohzrd / hkacade / hkpnd / tct / utd / uy / yebalnia ]

/prog/ - Programming

Programming
Name
Email
Subject
REC
STOP
Comment *
File
Password (Randomized for file and post deletion; you may also set your own.)
Archive
* = required field[▶Show post options & limits]
Confused? See the FAQ.
Options

Allowed file types:jpg, jpeg, gif, png, webp,webm, mp4, mov
Max filesize is16 MB.
Max image dimensions are15000 x15000.
You may upload5 per post.


9c29d7 No.4273

I often forget to put my values as const, and my code ends up as a mess of sometimes using const and sometimes not. To mitigate this, I was thinking of ways to have const be the default behavior.

I was thinking that it would maybe be possible to achieve this with preprocessor tricks. Something like this:


typedef int m_char;
#define int const char

#define mut(x) m_##x

int main() {
char x = 0;
mut (char) y = 0;

x++; // Error
y++;
return 0;
}

This, however, fails with types that use two keywords like "unsigned char".

Is there a way to have "unsigned m_char", or have "mut (unsigned char)" be translated into m_unsigned_char?

____________________________
Disclaimer: this post and the subject matter and contents thereof - text, media, or otherwise - do not necessarily reflect the views of the 8kun administration.

9c29d7 No.4274

Wouldn't it be best to just remember to make things const when you want them to be? This seems like the best way since you should be paying attention to that anyway, and it makes it very clear in the code that the value is const.

Disclaimer: this post and the subject matter and contents thereof - text, media, or otherwise - do not necessarily reflect the views of the 8kun administration.

9c29d7 No.4276

>>4274

It's hard to pay attention to that if the default should be constant unless I actually want to modify it. Since otherwise I pretty much have no reason to make things constant, as it works either way.

I don't intend to use this in code I release, as I don't intend to kill other people's eyes, just my personal stuff. In this case a compiler mod would also do the trick, but preprocessor tricks are generally easier.

Disclaimer: this post and the subject matter and contents thereof - text, media, or otherwise - do not necessarily reflect the views of the 8kun administration.

9c29d7 No.4277

After reading the preprocessor documentation, the best I could come up with is:

typedef char mut_char;
typedef unsigned char mut_unsignedchar;
#define char const char

#define mut(x, ...) mut_##x##__VA_ARGS__

int main() {
char x = 0;
mut (char) y = 0;
unsigned char a = 0;
mut (unsigned, char) b = 0;

x++; // Error
y++;
a++; // Error
b++;
return 0;
}

Which isn't exactly what I wanted, but it kinda works.

Disclaimer: this post and the subject matter and contents thereof - text, media, or otherwise - do not necessarily reflect the views of the 8kun administration.

9c29d7 No.4281

>>4276

Just build the habit of declaring variables const, man.

Disclaimer: this post and the subject matter and contents thereof - text, media, or otherwise - do not necessarily reflect the views of the 8kun administration.

9c29d7 No.4284

So… I decided to go full retard, if anyone's interested:

# This patch adds an option the the C compiler: -fdefault-const
# When this is enabled, everything will be a constant by default, and only be mutable if specified with the "mut" or "mutable" keyword.
# I tried to implement this the easiest way possible, by just flipping the const_p bit, and adding the keyword (reusing "mutable" from C++).
# Unfortunately, the fact that const_p is a single bit makes it hard to get everything right, as some checks assume that a keyword was specified only if the bit is on.
# As such, I had to flip the bit to "fix" a warning, but with a consequence: If -fdefault-const is enabled, it will only warn about "mut" being specified at the wrong places, and if not, it will only warn about "const".
# This was only tested and works with regular C. I haven't tested it on C++, so the option is unavailable there.
# The only effect this has on C++ is a new keyword: "mut", that means the same as "mutable".
# Also untested is compatibility with library headers such as libc.

--- gcc/c/c-decl.c
+++ gcc/c/c-decl.c
@@ -6128,6 +6128,7 @@

/* Type qualifiers before the return type of the function
qualify the return type, not the function type. */
+ type_quals ^= TYPE_QUAL_CONST * flag_default_const; // Only has effect on the warnings given by qualifying a function.
if (type_quals)
{
/* Type qualifiers on a function return type are
@@ -9499,6 +9500,7 @@
ret->expr_const_operands = true;
ret->typespec_kind = ctsk_none;
ret->address_space = ADDR_SPACE_GENERIC;
+ ret->const_p = flag_default_const;
return ret;
}

@@ -9546,6 +9548,11 @@
specs->const_p = true;
specs->locations[cdw_const] = loc;
break;
+ case RID_MUTABLE:
+ dupe = !specs->const_p;
+ specs->const_p = false;
+ specs->locations[cdw_mutable] = loc;
+ break;
case RID_VOLATILE:
dupe = specs->volatile_p;
specs->volatile_p = true;
--- gcc/c/c-parser.c
+++ gcc/c/c-parser.c
@@ -562,6 +562,7 @@
case RID_UNION:
case RID_TYPEOF:
case RID_CONST:
+ case RID_MUTABLE:
case RID_ATOMIC:
case RID_VOLATILE:
case RID_RESTRICT:
@@ -647,6 +648,7 @@
switch (token->keyword)
{
case RID_CONST:
+ case RID_MUTABLE:
case RID_VOLATILE:
case RID_RESTRICT:
case RID_ATTRIBUTE:
@@ -723,6 +725,7 @@
case RID_UNION:
case RID_TYPEOF:
case RID_CONST:
+ case RID_MUTABLE:
case RID_VOLATILE:
case RID_RESTRICT:
case RID_ATTRIBUTE:
@@ -2595,6 +2598,7 @@
declspecs_add_qual (loc, specs, value);
break;
case RID_CONST:
+ case RID_MUTABLE:
case RID_VOLATILE:
case RID_RESTRICT:
attrs_ok = true;
@@ -3928,6 +3932,7 @@
case RID_UNSIGNED:
case RID_LONG:
case RID_CONST:
+ case RID_MUTABLE:
case RID_EXTERN:
case RID_REGISTER:
case RID_TYPEDEF:
@@ -5994,6 +5999,7 @@
c_parser_consume_token (parser);
}
else if (c_parser_next_token_is_keyword (parser, RID_CONST)
+ || c_parser_next_token_is_keyword (parser, RID_MUTABLE)
|| c_parser_next_token_is_keyword (parser, RID_RESTRICT))
{
warning_at (c_parser_peek_token (parser)->location,
--- gcc/c/c-tree.h
+++ gcc/c/c-tree.h
@@ -251,6 +251,7 @@
cdw_noreturn,
cdw_thread,
cdw_const,
+ cdw_mutable,
cdw_volatile,
cdw_restrict,
cdw_saturating,
--- gcc/c-family/c-common.c
+++ gcc/c-family/c-common.c
@@ -548,7 +548,8 @@
{ "inline", RID_INLINE, D_EXT89 },
{ "int", RID_INT, 0 },
{ "long", RID_LONG, 0 },
- { "mutable", RID_MUTABLE, D_CXXONLY | D_CXXWARN },
+ { "mut", RID_MUTABLE, 0 },
+ { "mutable", RID_MUTABLE, 0 },
{ "namespace", RID_NAMESPACE, D_CXXONLY | D_CXXWARN },
{ "new", RID_NEW, D_CXXONLY | D_CXXWARN },
{ "noexcept", RID_NOEXCEPT, D_CXXONLY | D_CXX11 | D_CXXWARN },
--- gcc/c-family/c.opt
+++ gcc/c-family/c.opt
@@ -1174,6 +1174,10 @@
C++ ObjC++ Var(flag_declone_ctor_dtor) Init(-1)
Factor complex constructors and destructors to favor space over speed.

+fdefault-const
+C Var(flag_default_const) Init(0)
+Make all declarations constant by default, unless it's explicity mutable.
+
fdefault-inline
C++ ObjC++ Ignore
Does nothing. Preserved for backward compatibility.

This will, of course, require anyone compiling your code to have this patch, unfortunately.

Disclaimer: this post and the subject matter and contents thereof - text, media, or otherwise - do not necessarily reflect the views of the 8kun administration.

9c29d7 No.4296

>>4284

That's actually cool in a hacky way, but you are aware that that makes the language you are using not C, right? That will affect not only the code you write, but all imports as well, meaning many libraries will need their headers rewritten before you can use most of them.

Disclaimer: this post and the subject matter and contents thereof - text, media, or otherwise - do not necessarily reflect the views of the 8kun administration.

9c29d7 No.4301

>>4296

I'm aware. That's the reason for making it a compiler flag: if you want to compile external libraries alongside your own code, you just make them compile without that flag.

Library headers will need to be rewritten indeed, if they define structs you have to modify (as the members will be marked constant by default, and may need to be modified), or define any functions.

I'm writing an OS from scratch, so I don't feel the consequences as much as when working in an environment with tons of libraries.

Also, I updated it, fixed another warning related to functions with only void as a parameter.

http://chunk.io/f/4a714fd853a940dc9471c786121f6e04?lang=diff

Disclaimer: this post and the subject matter and contents thereof - text, media, or otherwise - do not necessarily reflect the views of the 8kun administration.

9c29d7 No.4322

> #define int

Yes, this seems like a good idea.

Disclaimer: this post and the subject matter and contents thereof - text, media, or otherwise - do not necessarily reflect the views of the 8kun administration.



[Return][Go to top][Catalog][Nerve Center][Random][Post a Reply]
Delete Post [ ]
[]
[ / / / / / / / / / / / / / ] [ dir / random / 93 / biohzrd / hkacade / hkpnd / tct / utd / uy / yebalnia ]