[ / / / / / / / / / / / / / ] [ dir / 27chan / asatru / leftpol / lewd / meguca / russian / scifi ][Options][ watchlist ]

/tech/ - Technology

You can now write text to your AI-generated image at https://aiproto.com It is currently free to use for Proto members.
Name
Email
Subject
Comment *
File
Select/drop/paste files here
* = required field[▶ Show post options & limits]
Confused? See the FAQ.
Expand all images

[–]

 No.818043>>818433 [Watch Thread][Show All Posts]

A lot of people on /tech/ complain about C++ being too bloated and C being too lacking. Why not adapt C++ features as C programming practices?

For example: for constructor/destructor autocalls,

void main(void) {
thing_t my_thing;
thing_construct(&my_thing);
// ...do things...
thing_destruct(&my_thing);
}
or the copy constructor,
thing_t thing1, thing2;
thing_construct(&thing1);
thing_construct(&thing2);
// ...
thing_copy(&thing1, &thing2);
// move constructor
thing_move(&thing1, &thing2);
//...

void thing_move(thing_t *to, thing_t *from) {
free(to->data);
to->data = calloc(from->size, 1);
memcpy(to->data, from->data, from->size);
thing_destruct(from);
}

It's not pretty, but I believe it's systematically similar. What does anon think?

 No.818056

A lot of people on /tech/ complain about C++ being too bloated and C being too lacking. Why not adapt C++ features as C programming practices?

Becuase if C programmers liked those features they wouldn't complain about them you idiot.


 No.818057

>>818056(Me)

>Who am I quoting?


 No.818061

But that's what people already do in C and have been doing since before C++.


 No.818069>>818381

Why doing what you propose, instead of writing C-style code in C++ and using C++ features only when they are useful in the project, rather than spamming them everywhere?


 No.818075

It would still lack of garbage collection.


 No.818080>>818397

>copy constructor in C

Nigger we avoid copying.


 No.818095>>818122

File (hide): 0b1df90eb319554⋯.jpg (9.03 KB, 250x241, 250:241, 51fYzbYoXFL._UX250_.jpg) (h) (u)

there is no reason not to use modern c++

its much better than c


 No.818122>>818123

>>818095

It's worth not using modern C++ just to keep the modern C++ programmers out.


 No.818123>>818131

>>818122

is parroting memes all you can do?


 No.818130

Because "bloat" is nothing but a meme.


 No.818131

>>818123

It's true, though. And I'm a C++ programmer.


 No.818214>>818241 >>818423

Strings in C are garbage.


 No.818228

You should read that book about doing oop with only ansi c


 No.818236>>818250 >>818275

Y'all niggas gotta read the code to Dungeon Crawl Stone Soup. It's so fucking easy to follow that you'll realize you only ever need blame yourself when you end up with unreadable C


 No.818241>>818360

>>818214

Stay bad.


 No.818250>>818262

>>818236


struct arena_error : public runtime_error
{
explicit arena_error(const string &msg) : runtime_error(msg) {}
explicit arena_error(const char *msg) : runtime_error(msg) {}
};

C++ was a mistake.


 No.818262

>>818250

OOP was a mistake.


 No.818275>>818300 >>818304

>>818236

This is some quality garbage, anon. Thanks for the humor.


const char* card_name(card_type card)
{
switch (card)
{
case CARD_VELOCITY: return "Velocity";
case CARD_EXILE: return "Exile";
case CARD_ELIXIR: return "the Elixir";
case CARD_STAIRS: return "the Stairs";
case CARD_TOMB: return "the Tomb";
case CARD_WILD_MAGIC: return "Wild Magic";
case CARD_ELEMENTS: return "the Elements";
case CARD_SUMMON_DEMON: return "the Pentagram";
case CARD_SUMMON_WEAPON: return "the Dance";
case CARD_SUMMON_FLYING: return "Foxfire";
case CARD_RANGERS: return "the Rangers";
case CARD_SHAFT: return "the Shaft";
case CARD_VITRIOL: return "Vitriol";
case CARD_CLOUD: return "the Cloud";
case CARD_STORM: return "the Storm";
case CARD_PAIN: return "Pain";
case CARD_TORMENT: return "Torment";
case CARD_WRATH: return "Wrath";
case CARD_WRAITH: return "the Wraith";
case CARD_SWINE: return "the Swine";
case CARD_ORB: return "the Orb";
case CARD_ILLUSION: return "the Illusion";
case CARD_DEGEN: return "Degeneration";
case CARD_FAMINE: return "Famine";

#if TAG_MAJOR_VERSION == 34
// Removed cards.
case CARD_MERCENARY: return "the Mercenary";
case CARD_ALCHEMIST: return "the Alchemist";
case CARD_CURSE: return "the Curse";
case CARD_VENOM: return "Venom";
case CARD_FORTITUDE: return "Fortitude";
case CARD_HAMMER: return "the Hammer";
case CARD_XOM: return "Xom";
case CARD_FEAST: return "the Feast";
case CARD_WARPWRIGHT: return "Warpwright";
case CARD_SUMMON_UGLY: return "Repulsiveness";
case CARD_PLACID_MAGIC: return "Placid Magic";
case CARD_CRUSADE: return "the Crusade";
case CARD_HELM: return "the Helm";
case CARD_BLADE: return "the Blade";
case CARD_SHADOW: return "the Shadow";
case CARD_POTION: return "the Potion";
case CARD_FOCUS: return "Focus";
case CARD_HELIX: return "the Helix";
case CARD_DOWSING: return "Dowsing";
case CARD_BANSHEE: return "the Banshee";
case CARD_SOLITUDE: return "Solitude";
case CARD_PORTAL: return "the Portal";
case CARD_WARP: return "the Warp";
case CARD_BATTLELUST: return "Battlelust";
case CARD_METAMORPHOSIS: return "Metamorphosis";
case CARD_SHUFFLE: return "Shuffle";
case CARD_EXPERIENCE: return "Experience";
case CARD_SAGE: return "the Sage";
case CARD_TROWEL: return "the Trowel";
case CARD_MINEFIELD: return "the Minefield";
case CARD_GENIE: return "the Genie";
case CARD_GLASS: return "Vitrification";
case CARD_BARGAIN: return "the Bargain";
case CARD_SUMMON_ANIMAL: return "the Herd";
case CARD_SUMMON_SKELETON: return "the Bones";
case CARD_WATER: return "Water";
case CARD_SWAP: return "Swap";
#endif

case NUM_CARDS: return "a buggy card";
}
return "a very buggy card";
}

>how do i array


 No.818300>>818304

>>818275

Let me guess, translations are done with pre-processor macros as well?


 No.818304>>818336

>>818275

>>818300

I didn't think it could actually be that bad.

>ability.cc

>literally the first source file

>3800 LOC

>80 lines of #include

>almost half of the file is made up of a single switch statement

> https://github.com/crawl/crawl/blob/master/crawl-ref/source/ability.cc#L1796


 No.818336>>818399

>>818304

What's wrong with a big switch statement?

How would you be doing it?


 No.818360>>818400 >>818423 >>818452

>>818241

I am working on a dataabase driven app write now, and goddamn, the number of mallocs required is stupid. String concatention in C is retarded.


 No.818381

>>818069

Its as I'd that's already best practice.


 No.818397>>818401 >>818509

>>818080

and how do you do that? can you be more specific?

in any nontrivial program there will be some copying somewhere.


 No.818399>>818431

>>818336

When not written by a Pajeet, code like this would compartmentalize rather than just glue fucking everything into a giant switch statement. A good way to realize what's wrong and also think about the right way to do it would be to ask yourself, "how would I add support for mods here?". You'd have some sort of struct representing things like this that would have its callback registered with the ability code. The result would be an ability.cc that is very small, ability code that could be grouped into its own file, and ability.cc could use datastructures to do the lookups rather than potentially roll through hundreds of comparisons looking for a match.


 No.818400>>818511

>>818360

Maybe it's just your inexperience? C isn't Java, we avoid allocations. Software that has to be fast doesn't even use malloc.


 No.818401>>818433

>>818397

I'm not sure how I can describe it, but it's really rare that good C and C++ copy anything. For an example, I just grepped 100k LoC of my C++ code for them and there were only 3.

There's probably a difference here depending on what language you came from. If you went from C to C++, you're unlikely to do something like add a copy constructor so you can let stl containers value copy your data because you know how fucking stupid what's going on under the hood is and know to avoid it.


 No.818423>>818431 >>818466

>>818214

>>818360

Dennis Ritchie and Ken Thompson were the first Pajeets.

>We went to lunch afterward, and I remarked to Dennis that easily half the code I was writing in Multics was error recovery code. He said, "We left all that stuff out. If there's an error, we have this routine called panic, and when it is called, the machine crashes, and you holler down the hall, 'Hey, reboot it.'"


 No.818431>>818626

>>818399

I don't think you understand how their implementation of abilities works. Your solution is more code, more files, and undoubtedly less efficient.

>>818423

You keep using this joke as if it were the core design principle of UNIX. Tons of error recovery code is a waste of time, and bloat, unless you're writing a fault-tolerant financial system.


 No.818433>>818625 >>818804

>>818043 (OP)

Because that defeats the purpose. The C++ people are saying that the language should do that for you. The C people argue that when the language does, unoptimized code is slow do to containing numerous operations that don't need to happen.

Take this code:


std::string makeString()
{
return "Hello";
}

int main()
{
std::string someString = makeString();
}

A C person looks at this and says: makeString() is going to construct a temporary string object, allocating memory for and copying "Hello". Then, it is going to pass that to construct someString, which will allocate memory for and copy "Hello" again. That's 3 copies of "Hello" in memory.

A C++ programmer will note that the lowest optimization setting will return-value optimize away one of those copies, and one can modify someString without the program dying.

The C code is error prone, and expert C developers have shown time and again that they don't actually have the discipline to write correct C, let alone C-with-ad-hoc-classes.

The C++ code requires optimization to have suitable performance, and attracts Java programmers (the number of corporations that use Java means that there are a lot of shitty developers who know Java).

>>818401

The only problem I've had with this is that you complex ownership rules. I let STL containers copy my data because then I know that the container owns the data. And then the Java-trained junior devs won't create memory leaks when they manipulate the container.


 No.818452>>818513

>>818360

Use asprintf()


 No.818466

>>818423

QNX and MINIX3 are resilient enough for emdedded use though.


 No.818509

>>818397

Pass pointers.


 No.818511>>818620 >>818627

>>818400

Suppose you want to create a select /where SQL query from. From isolated strings. What do you do? Allocate a new string and copy everything into it. You could have a fixed size static buffer (fast), but then you aprori limit query length, and waste arbitrary space extending that limit. How long is the longest query?

C++ you can concatenate strings. (which probably just invokes its version of memory mangement to malloc anyway).


 No.818513

>>818452

My droog. asprintf is implict malloc.

but C++ strings probably implicit malloc anyway, i didn't know about asprintf, and it cleans up my code


 No.818620

>>818511

If you're sending SQL queries, malloc() is not going to be your bottleneck (the disk and/or network are), so you might as well just malloc every query string.


 No.818625

>>818433

>I let STL containers copy my data

No, this is just bad. You have no excuse for this now that you have things like unique_ptr built in. Fix your code.


 No.818626

>>818431

>Your solution is more code, more files

True. Abstraction has a cost.

>and undoubtedly less efficient

Untrue. I'd be able to avoid that massive number of comparisons they're doing by having some form of map.


 No.818627>>818629 >>818738

>>818511

>Suppose you want to create a select /where SQL query from. From isolated strings. What do you do? Allocate a new string and copy everything into it.

It sounds like you're trying to solve a problem incorrectly and that's the cause of your shitty code. You shouldn't be assembling SQL query strings dynamically. It's not 1999 anymore. Query strings should be static and prepared. Dynamic arguments to queries should be passed via positional APIs. Queries that need to change depending on the situation should be handled by stored procedures plus positional APIs. Proper SQL has almost nothing to do with query strings these days, they're only used at startup.


 No.818629>>818644

>>818627

This. Views, functions and prepared statements are your friends, and stop making your code vulnerable to SQL injection.


 No.818644>>818661

>>818629

You can either use prepared queries and bind values, or you can quote any SQL metacharacters. It doesn't matter which one you do, so long as you do it correctly. I often use both, depending on what's easier.

But that's just for sanitizing user input. Optimization might have different needs, but it's not a given that everything has to be optimized with prepared queries. I've worked on projects where low volume transactions were the norm, and the business logistics made high volume basically impossible anyway. Everything depends on the circumstances at hand.


 No.818661>>818816

>>818644

>It doesn't matter which one you do, so long as you do it correctly.

It does matter. Passing dynamic query strings is inefficient as nothing can be cached, it's having to parse and replan queries all the time, and you're grinding user data through escaping which is both slow and extremely dangerous. Even good webdevs know not to do that so I can't call it webdev-tier.

>sanitizing

That word even being in your vocabulary is a huge red flag. You mean 'escaping' in this context not 'sanitizing' but you've got a third world PHP Pro stink to you.


 No.818738>>818847

>>818627

When your so abstracted away in your rails framework that you have no idea what the reality is.

Wtf. Ultimately, queries are dynamic. Why? Because we don't know apriori what to search the database for sc. If i knew apriori I was going to search the database for rows where firstname='example' . I wouldn't have a database. I would have a textfile with the values cached.

The second the query becomes dynamic (and useful) , you have string allocation issues in C. Why? Because libmysqlclient mysql_real_query takes a string argument. So ultimately, you, or some framework are going to malloc a string to go there, because C doesn't have string concatenation.

I wrote a wrapper function that is passed a hash and generates a syntactically valid SELECT/Where statement (thats sanitized) from pairs in the hash and a table name as an argument. But you still have to malloc the string.

If rails/nodejs whatever the fuck trend language your using now has a wrapper function to generate query strings from hashes (like I am dong anyway), know that its still allocating a new string, because ultimately, your using the C ABI on x86 which doesn't have string concatenation natively.

Your argument of just use rails is retarded.

Or I don't understand what your talking about


 No.818804>>818842

>>818433

I don't know alot about C++ , but I just assembled this , and debugged with gdb, and it looks like main has a local variable someString ,which is passed as a pointer to makeString, which calls the C++ runtime to allocate a string at its address directly.

So, it seems this code doesn't 3 times. It copies "Hello" from .data to a string object once in allocating the string, directly where it belongs from makeString().


.file "test.cpp"
.section .ctors,"aw",@progbits
.align 8
.quad _GLOBAL__I__Z10makeStringv
.LC0:
.string "Hello"
.globl _Unwind_Resume
.text
.align 2
.globl _Z10makeStringv
.type _Z10makeStringv, @function
_Z10makeStringv:
.LFB1422:
pushq %rbp
.LCFI14:
movq %rsp, %rbp
.LCFI15:
pushq %rbx
.LCFI16:
subq $40, %rsp #Create locals No Locals! Yikes
.LCFI17:
movq %rdi, -32(%rbp) #save RDI (argument, pointer to local in main) to local
movq -32(%rbp), %rbx #move that same local to %rbx ??
leaq -9(%rbp), %rdi #load local variable address to %rdi (argument to new function)
call _ZNSaIcEC1Ev@PLT
leaq -9(%rbp), %rdx #Load address of another local into %rdx
leaq .LC0(%rip), %rsi #load address of SOMETHING? into %rsi
movq %rbx, %rdi #save old return value(address of someString local) of fn _ZNSaIcEC1Ev@PLT as %rdi (first argument)
.LEHB0:
call _ZNSsC1EPKcRKSaIcE@PLT #This inits string object, now data is contain in string.
#rbx now contains address of string
.LEHE0:
leaq -9(%rbp), %rdi
call _ZNSaIcED1Ev@PLT #what is this? #no return value. takes argument local variable.
jmp .L27
.L30:
movq %rax, -40(%rbp)
.L28:
movq -40(%rbp), %rbx
leaq -9(%rbp), %rdi
call _ZNSaIcED1Ev@PLT
movq %rbx, -40(%rbp)
movq -40(%rbp), %rdi
.LEHB1:
call _Unwind_Resume@PLT
.LEHE1:
.L27:
movq -32(%rbp), %rax
addq $40, %rsp
popq %rbx
leave
ret
.
main:
.LFB1423:
pushq %rbp
.LCFI18:
movq %rsp, %rbp
.LCFI19:
pushq %rbx
.LCFI20:
subq $40, %rsp #create local variables. only local variable is someString!! yikes. 40
.LCFI21:
leaq -16(%rbp), %rdi #load the address of local variable into RDI (argument to makestring)
.LEHB2:
call _Z10makeStringv #call makestring
.LEHE2:
leaq -16(%rbp), %rsi #load address of that local variable into rsi
movq _ZSt4cout@GOTPCREL(%rip), %rdi #some kind of local variable gaurd argument
.LEHB3:
call _ZStlsIcSt11char_traitsIcESaIcEERSt13basic_ostreamIT_T0_ES7_RKSbIS4_S5_T1_E@PLT //call
.LEHE3:
movl $0, %ebx
leaq -16(%rbp), %rdi #load address of local variable into rdi
.LEHB4:
call _ZNSsD1Ev@PLT
.LEHE4:
movl %ebx, -28(%rbp)
jmp .L31
.L34:
movq %rax, -40(%rbp)
.L32:
movq -40(%rbp), %rbx
leaq -16(%rbp), %rdi
call _ZNSsD1Ev@PLT
movq %rbx, -40(%rbp)
movq -40(%rbp), %rdi
.LEHB5:
call _Unwind_Resume@PLT
.LEHE5:
.L31:
movl -28(%rbp), %eax
addq $40, %rsp
popq %rbx
leave
ret


 No.818816>>818854

File (hide): 4c00b73e412f07a⋯.png (1.18 KB, 16x16, 1:1, weirdPixelMonkey_0.png) (h) (u)

>>818661

Did you even read my post you triple-decker nigger? I explained you don't always have to care about optimizing that stuff, and especially it matters jack all when the disk or network I/O is the bottleneck.

And any decent library has a convenient way to escape metacharacters, you don't have to do it by hand like a monkey. And if you weren't a monkey, you'd know that.


 No.818842

>>818804

>#what is this? #no return value. takes argument local variable.

It's the destructor for std::allocator<char>, apparently.

Also, looks like you forgot to add -O3 :^)


 No.818847>>818864

>>818738

>The second the query becomes dynamic (and useful) , you have string allocation issues in C. Why? Because libmysqlclient mysql_real_query takes a string argument.

You really need to learn how to use a database properly before writing a library for one as your head is full of rocks. Again, like I said, you don't use query strings anymore past startup. You use prepared statements of static strings:

https://dev.mysql.com/doc/refman/5.7/en/c-api-prepared-statements.html

And when queries do need to be more dynamic than the number of parameters you use prepared statements to stored procedures:

https://dev.mysql.com/doc/refman/5.7/en/create-procedure.html

It's a totally different protocol under the hood when you do this. Instead, you're forcing the thing to use a compatibility API from the '90s. Even the mistake that is MySQL has a C API like this but you should really be using PostgreSQL. But, baby steps.

>Your argument of just use rails is retarded

I don't even know rails, I'm a C programmer. Get your head on straight, anon.


 No.818854

>>818816

>I explained you don't always have to care about optimizing that stuff

No, you made an attempt to justify unsafe Pajeetcode. This was you:

>can quote any SQL metacharacters

>can quote any SQL metacharacters

>can quote any SQL metacharacters

Disgraceful. A shameful display. Apologize to your father for disappointing him.


 No.818864

>>818847

>Prepared statements transmit data between the client and server using C language variables on the client side that correspond to SQL values on the server side. If there is a mismatch between the C variable type on the client side and the corresponding SQL value type on the server side, MySQL performs implicit type conversions in both directions.

Am idiot. Can confirm. Thanks for that. Wish I started with this API. First on the documentation is mysql_real_query . Fuck.

Writing it this retarded way was still insightful. I am glad mysql exposes another API.




[Return][Go to top][Catalog][Screencap][Nerve Center][Cancer][Update] ( Scroll to new posts) ( Auto) 5
49 replies | 2 images | Page ???
[Post a Reply]
[ / / / / / / / / / / / / / ] [ dir / 27chan / asatru / leftpol / lewd / meguca / russian / scifi ][ watchlist ]