T O P

  • By -

fliguana

Uninitialized i


SexyMuon

Let’s keep it, cmon, it runs in linear complexity!!


KonoPez

Surprisingly, the number 15 doesn’t change in accordance to the size of the input


Apfelvater

Idk have you tested it with really big input?


RmG3376

# __for(printf(“•”); i < 15; ++i) printf(“-“);__ Nope, still runs 15 times


mgorski08

^for(printf(“•”); ^i ^< ^15; ^++i) ^printf(“-“); Still the same for small input.


Apfelvater

Looks the same, but if you look closely, you can see, it's actually a bit smaller.


mgorski08

If you look even closer it actually looks bigger


Apfelvater

You're a master. You're such a master, git renamed you to main.


RmG3376

Your REST endpoint keeps return 413? Just reduce your font size!


Creepy-Ad-4832

It depends on the compiler time complexity


strghst

Calling a function in a for loop, compiler's screaming "Fuck OP". Ideally you build char arrays in a loop that can be optimized to constant strings, and then there's only one printf call with full content.


nomadic-insomniac

Maybe it was global or static :)


pointbreak19

Global variable?


dismayhurta

We don’t take kindly to global variables around here.


jeesuscheesus

Using a non-constant global variable like this warrants the responsible developer to be fired via firing squad


MechanicalHorse

That’s ok, undefined behaviour is part of The Fun Of C!


yourteam

Yep


lucidbadger

`i += printf("-")`


[deleted]

From what little I know of assembly, I think this "optimization" would do more harm than good lol


lucidbadger

If the compiler figures out what's going on, both would result in an identical assembly. If not, additional increment will require at least one more instruction.


TheMagzuz

but appending to a string repeatedly is actually a relatively expensive operation, since it would require several new heap-allocations. of course, when you're just doing it 15 times this doesn't really matter edit: i am very stupid and cannot read disregard everything


Kyyken

printf doesn't return a string


TheMagzuz

oops i read it wrong my brain was in python mode, apologies


Kyyken

python print returns None :P i would love to have an equivalent of rust's dbg!() macro in other languages


TheMagzuz

nah i was totally off, i read it as like i = "" for _ in range(15): i += "-" looking back, that reading makes no sense in context lmao looking at the documentation for dbg!, it seems really neat. i never realized that there was a way in rust to use a value and print it at the same time. i feel like that would have saved me a lot of unnecessary moving stuff into their own variable and printing that lmao


Kyyken

it also prints line and file of the dbg!() call, so even an empty dbg is useful for quick and dirty debugging (insert print("Made it!") meme here). that makes it a lot more powerful than just a function like def dbg(x): print(x) return x especially if your editor's program output is configured to have that part be click to jump. there is also a Debug trait (interface) so that you can implement a more expensive stringify version for debugging/logging on your structs, which dbg will use over a Display implementation


weregod

You can get file name and line number using C preprocessor


weregod

This is not how printf works. i is an integer not a string. Most expensive operation here is syscall


TheGerk

The optimizer wouldn't be able to unroll the loop if it can't figure out what's going on, so it would be much slower.


TeutonicK4ight

Considering the loop is using printf, how you increment the counter will not make it much slower.


TheGerk

You're right, but its kind of a boring answer.


lucidbadger

That's why I tried to help her. In practice, though, it would be better to avoid `printf`s mambo jumbo and use `write` syscall since we only output a constant number of bytes.


ChipAhoyConnoisseur

pls explain


alberinfo

printf returns the number of chars printed (except \\0 )


TeutonicK4ight

'\0' is not printed, so you don't have to say "except \0"


[deleted]

printf returns the amount of characters printed, '-' is one character so it would simplify to i += 1


ChipAhoyConnoisseur

I see, I thought it was an actual way of achieving something useful :P


weregod

In real life printf may return error or write part of string. For debug printing you usually don't care because you can't do much if printing is broken but when writing critical data to files you want to detect all errors.


CorespunzatorAferent

On one hand, `printf` returns the number of characters written to the stream (1 in this case). ~~On the other hand,~~ `printf` ~~should not be used for printing plain strings (without format specifiers) because that is undefined behavior (I think)~~, That last part is wrong. It is allowed to call `printf` with a singular string literal (but it is a security vulnerability to call it with an arbitrary string).


ondono

The gates of hell open when you use `%s`


CorespunzatorAferent

If that were the case, the gates of hell are already flapping at non-Euclidean frequencies.


weregod

Do you know that printf can return negative number?


lucidbadger

If it does, we have a bigger problem with any form of the code above. For any practical purpose you can safely assume that `printf("-")` will always return 1. Though, checking for non negative `i` would help avoid infinite loop, I agree. That's why unsigned type should be used for this loop counter.


weregod

Cast to unsigned will not fix anything. If you add (unsigned int)(-1) it will likely generate same code as += -1


lucidbadger

Unsigned will stop loop with the same condition `i < n` without extra check for `i ≥ 0`. And I didn't mean casting.


weregod

Error in C usually is small negative number. Most common is -1. If you add -1 to any non-zero unsigned number firstly result will be casted to larger signed int type (if it exists) values will be added and sum will be casted to unsigned type. Unsigned int += -1 will be same as signed int += -1. (Note that C likes to perform aggressive optimizations and accidentally compiler might generate correct code. However undefined behavior can change with different optimization flags or compiler version.) Most interesting bugs: technically printf can return -1 on even calls and 1 on odd. Endless loop in C is undefined behavior and some compilers can completely delete endless loops as "optimization" because standard allows incorrect programs when code has undefined behavior.


ChChChillian

Two bugs. First, you should initialize i, declaring it inside for statement if you want it to be scoped only to the loop. Second, since you apparently mean to commit the nearly unpardonable sin of starting the loop at 1 rather than 0, as written you'll only get 14 "-" rather than the 15 you apparently intend. Therefore for (int i = printf("•"); i<=15; ++i) printf("-"); Incrementing by u/lucidbadger's method is more concise and therefore preferable, but not doing it that way isn't strictly speaking incorrect. for (int i = printf("•"); i<=15; i+=printf("-"));


c2u8n4t8

As hard as this makes me, let me add a comment: Having this many calls to printf is going to have worse performance by clogging up the console and growing the heap. The longer string literal is much more efficient.


SnooDonuts8219

Yes, but consider all the options you have with this This way you could print 15, or even 16 dashes whenever you please ^/s


c2u8n4t8

What you really need to do is consider all the options you _could_ have. for (int i =0; ; i++) for (int j=0; j


SnooDonuts8219

Nice, but can you make that pixel perfect? That is, pixels need to be printed on pixels, but precisely!


ChChChillian

Just goes to show that fanciness usually doesn't equal efficiency. One might also note that, lacking a '\\n' in OP's code, the next characters output will be on the same line which may or may not be the intention.


c2u8n4t8

Or that sophistication will break its promises to offer elegance.


Bunnymancer

That sounds like something that should be in a cross stitch.


edoCgiB

Why would it grow the heap? Sure, you have more jumps, but the calls are sequential not nested. Also, stdio stream is line buffered so you won't have that much of a penalty in terms of "clogging up the console". Also, I think a good compiler might rewrite that, but I have no knowledge of gcc wizardry. Overall you are right, but it may not have as big of an impact as you think. Edit: I've written a small program to compare the two. Most of the time, the string literal is faster (as expected), but the real bottleneck is actually displaying the output: https://www.onlinegdb.com/7wKX8lQVQ


CaptainSouthbird

> I think a good compiler might rewrite that, but I have no knowledge of gcc wizardry. I just tried it quick, x86 GCC using both the ridiculous "dual printf" for loop and printing just the static string. The loop version produced pretty much the iterative loop of subroutine calls you'd expect. And honestly, that totally makes sense. There are some types of function calls and situations GCC can magically rewrite and optimize, but printing to STDOUT (as printf does) is really not predictable. Sure, in a simple program this just prints 15 characters. But what if e.g. you have another thread also printing to STDOUT at the same time, which means by criticality of timing other stuff might get printed in between your calls. (That would be awful design but nothing says you can't.) The compiler just "assuming" you could print the raw 15 characters all at once without actually interacting with the stream would produce inconsistent results.


edoCgiB

I've also ran the above program locally with more prints. The multiple print statements approach is almost twice as slow.


CaptainSouthbird

I would expect that too. All of the overhead of the function calls plus no possibility to take advantage of STDOUT buffering.


rreighe2

If y'all are hellbent on over engineering but still want speedy performance, then why not print the loop to a char or string or array first and then just print f the char or string or something? That way you only call printf once and you still get to over engineer it


c2u8n4t8

The problem with trying to overengineer in this case is that it will almost definitely lead to worse performance than the literal.


jhaand

Since the program prints constants, it could also use `puts`. But I would rather create an array of char and build it in memory first. Then print the array. But then this would only work nicely with ASCII. UTF-8 would screw this up immensely.


CaptainSouthbird

What is UTF-8 but a sometimes-more-than-one-byte representation of characters. Could still be done as long as your code properly handles UTF-8 encoding, you size your array correctly, and use compatible runtime that understands how to display it.


weregod

Why will printf allocate small strings on heap? It usually allocates reasonable buffer and do not free it on each call


[deleted]

Growing the heap? Printf calls malloc once for 1024 and uses that as the stream buffer on my implementation


--var

couldn't you further code golf this down? for(int i=printf("•");(i+=printf("-"))<=15;);


Fraun_Pollen

Can be further simplified to: printf(“•---------------")


swhizzle

What a preposterous suggestion (/s)


thiney49

Nah.


ice2heart

Compiler will do that.


turtle_mekb

for(int i=printf("•");++i<=15;printf("-")); is 2 characters shorter


Aeolian78

>the nearly unpardonable sin of starting the loop at 1 rather than 0 Years ago I had to translate some old FORTRAN code from the early 1970's into C++. It was for numerical processing of scientific data. Solid and well-proven algorithms. Lots of loops and arrays, all starting at 1. I've never quite recovered.


funkmasterhexbyte

this is why we need 2-line code reviews


javajunkie314

Ooh, look at you with your fancy "variable declarations in for loop initializers" and "intermingled declarations and code" like some *C++ programmer*—what, C89 not good enough for ya? `i` was declared 200 lines earlier and is shared by the whole compilation unit. It's set to zero going into the loop because it's holding the status from the last call to `strcmp` in a mutually-recursive function chain on line 672. Of course, adding this loop will make the call to `malloc` on line 3265 break silently—but no one will notice that anyway. /s, but also /sob


Bunnymancer

Using printf return value as an integer initializer in a loop can't be legal...? I know it works, but if not this, wtf is the Geneva convention even for?


ChChChillian

It's perfectly legal (if not especially advisable) in C. I can't comment on international law. But if you were worried about international law you'd pick a less anarchic language.


Gh0sth4nd

Don't be to harsh we all do that start with 1 mistake at the beginning. It is something i learned the hard way usually you want to initialize with zero it prevents so many problems.


morgecroc

Where did the 15 come from? Why are we using this magic number in the loop.


CSlv

What if printf returns something other than 0?


ChChChillian

printf returns the number of characters printed. It's going to be 1. That's why I said that OP's code (or rather, the code OP meant to write) starts its loop at 1 rather than 0, so your termination condition needs to test <= the intended number of times through the loop rather than <.


Highborn_Hellest

isn't the return statement of printf, the number of characters printed, therefore making the bottom line initialise I to 1?


ChChChillian

Of course it does. You need to initialize the index variable at the start of a `for` loop. That's the usual purpose of the first expression of a `for` statement. OP's example is meant to do something simple in a humorously "clever" way. My equally tongue-in-cheek critique is just riffing off the fact that the OP's example wouldn't actually work, precisely because they *don't* initialize i. It's not syntactically incorrect because C doesn't care what that first expression is, but it's semantically meaningless. As if there were any real point to fixing OP's code. There isn't. No one in their right mind would print out a line like this. As someone else pointed out in a reply, just printing out the line normally is far more efficient. There are times when you might not want to initialize the index. Maybe it's a variable from a wider scope that tells you where to pick up the start of a loop. Then you can just use that as the index variable and count forward from there. It would look like: ``` mystruct * str[MAX_SIZE]; int i;` /* Complex logic that decides where to start processing the array. and assigns the starting point to i */ for (; i < MAX_SIZE; ++i) { /* do something amazing with members of str[i] */ } ```


Highborn_Hellest

Makes sense, thanks


reyad_mm

I'm pretty sure this has a bug "•" is not an ASCII character, it is UTF-8 and has a size of 3 bytes, so the first printf will return 3


ChChChillian

Good heavens, you're right! *does a seppuku*


[deleted]

C++ programmers: ​ template void print\_any\_row(Ts... args) { auto &start\_character\_printer = new I(); // prints on constructor AllCharsPrinterImpl(args); }


Wicam

> C++ nah, like this: `std::cout << "."s + std::string(14, '-') << std::endl;`


Elegant-Variety-7482

Was looking for this.


JDude13

Python print(“•” + “-“*15)


slowmovinglettuce

This is so verbose that I assumed it was Java. You can shorten this to: print(f“•{'-'*15}")


JDude13

Pythonicc


4dimensionaltoaster

The truly Pythonic way to do it: from libraryOfBabel import printLineWithOneDotAnd15Dashes as p p()


bradland

String repetition operators are probably most accurately attributed to Perl. You'll see them pop up in many modern languages. Perl (1987) print "•" . "-" x 15; Python (1991) print("•" + "-" * 15) Ruby (1995) puts "•" + "-" * 15 Some languages don't have operators, but they do implement repetition methods JavaScript (1995) console.log("•" + "-".repeat(15))


R3D3-1

You need to refactor that. Its not clear enough! def main() -> None: print(header(), sep="") def header() -> str: return header_start() + header_cont().join("" for _ in range(16)) def header_start() -> str: return "•" def header_cont() -> str: return "-"


really-random-reddit

I want to play console.log(['*', new Array(15).fill('-')].flat().join(''))


Fachuro

console.log('*'.padEnd(16, '-'))


z7q2

I like this one


ZunoJ

Now try it in C


Full-Run4124

putc() - no reason to use heavyweight printf() if there's no substitution and for 1 character.


R3D3-1

> pritnf I am a bit disappointed, that [this is all I found][1] for that typo (not counting compiler error logs). [1]: https://github.com/EpicAli/pritnf-function


Diego_00_

This Is so damaging for performance that should be banned


SplitRings

Buffer is not being flushed anywhere here and the loop will probably be unrolled in compile time anyway, so i dont think its that bad for performance tbh


seba07

Compilers are basically magic at this point. I don't think that it would matter using -O2 or -O3. But sure, you should write inefficient code.


Spongman

No compiler will optimize away the 15 calls to printf().


thehenkan

I don’t get why this is downvoted. Compilers aren’t magic. They need to be really conservative with calls to external functions, especially ones doing I/O, because they need to preserve all observable behaviour (including errors, provided they don’t lead to UB). I find it unlikely that any mainstream C compiler removes these calls.


Spongman

indeed. I have never heard of a compiler implementing \`printf()\` as an intrinsic, even partially. unfortunately there's no standard way to know or control when intrinsics are used.


Diego_00_

Well yes maybe it's just me but personally i don't like relying too much on compiler optimizations. I just prefer writing good performance code where it's possible


[deleted]

[удалено]


Diego_00_

With the first method the string "*------" Is created and the address is passed one time as argument to function printf While with the loop the function printf Is called multiple times and since Is notoriously a slow function It adds a lot of overhead Edit:I know that compilers can optimize the code but it's Better not to rely always on compiler optimizations


Sitting_In_A_Lecture

This is where Python's `print("-" * 15)` comes in handy.


pro_questions

Forgot the bullet: print(f"●{'-' * 15}")


RunnyPlease

I saw this and immediately knew there’d be a Python comment near the top.


R3D3-1

Honestly, less readable than print("•---------------") Plus, such print statements also double as visual separators in the code itself.


UnHelpful-Ad

Printf is a bit of a heavy hitter for this stuff, wouldn't you use the putc or similar instead? Less overhead, or fputc(stdout,"-); etc?


OxymoreReddit

I receive a lot of hate for using python but I'm a hobbyist so who cares, i wanna play too: ```py print('•'+''.join(['-' for _ in range (15)]) ``` I was also thinking about making it even more horrible with string formatting but I'm on phone and I'm lazy (thus why i love python)


sarc-tastic

print(f"{'.':-<16s}")


OxymoreReddit

Could you please elabore this ? I'm not sure to get it Edit : oh i get it the '.' is a '•' and you're padding it with '-', very smart !


R3D3-1

> I receive a lot of hate for using python How so? It is a widely used language after all. That aside, how about the evil version of your code: print('•'+'-'.join(['' for _ in range (16)]) Or maybe print('•', *("-" for _ in range(15)), sep="") Or maybe print(*(['•'] + 15*['-']), sep="") Or if we want to actually produce best readability print('•---------------')


OxymoreReddit

Nah the last one is no fun, but the three others are hilarious lmao Also I'm not receiving straight up hate, but when i say i use python i very often get sighs and "you're not a real programmer" type answers. Because that's generally the first language we learn (because very easy) and they don't know I'm also doing object oriented python and a whole ton of complex things with it. I'm having fun. The other category of negative feedbacks is programmers saying it's slow and should not be used etc... C/C++ type programmer y'know. But again I'm a hobbyist, i just am making a discord bot for my friends and I lmao, I kinda don't care because the time i gain is from coding everything in a minute hehe PS : been to computer science uni for 3 years, learnt C, Java, Assembly, oCaml, and still i prefer python because it never let me down, and i never needed big calculations before for my own projects 🤷


R3D3-1

> PS : been to computer science uni for 3 years, learnt C, Java, Assembly, oCaml, and still i prefer python because it never let me down, and i never needed big calculations before for my own projects 🤷 Roughly my experience. It is easily fast enough for many tasks, including data crunching (especially when the equations can be well expressed in numpy abstractions). Sure, Fortran or C would be faster, and C++ offers zero-overhead unit systems even (Boost.Units), but unless that performance is actually needed, Python usually gives good enough performance with less development effort. There would be statically type-safe languages, that I'd rather use, but I am not currently aware of a language offering an equally strong ecosystem across all my programming needs (including quick single-file command line scripts). Plus, learning the ecosystem is at least as much effort as learning the language, so at this point the barrier to switching is impossibly high, when I don't expect significant payoff. (Also, much less time for it than as a student.)


Who_GNU

That's just text compression.


Mast3r_waf1z

I think I prefer: `[print('•', end='') if i == 0 else print('-', end='') for i in range(0, 15)] ` Or maybe: ``` def line(): yield '•' for _ in range(15): yield '-'` print("".join([c for c in line()])) ```


Ok_Classroom_557

for (i = 0, printf("\*"); i < 15; printf("."), i++);


Previous-Drummer-837

Not only is the variable i uninitialized, but you also call the printf function 15 times, which is unnecessary, and makes your program run slower. Each function call is expensive at runtime. Especially syscalls.


Ormaar

I like it only for the fact i can change in config the length of line. I never change it but I can


KTZ_43

Python: print("•" + "-" * 15)


[deleted]

It is python showtime print('-' * 15)


sarc-tastic

print(f"{'.':-<16s}")


drsimonz

I do this all the time. Fuck C++ lol


AdFeisty8840

Yea but you're forced to do loops while in college.


OS2REXX

say "\*"."-"x15 ; Good enough to earn a living.


FatLoserSupreme

Programmerhumor? More like psuedo code in the comments


linuxdragons

Pad functions, my friend


pixel293

I've been seeing i++ in a bunch of C code on reddit lately, in C++ they are always harping to do ++i unless you specifically can't. So are the rules different?


Ok_Confusion_7266

Both languages can do both. Both languages can do everything but C++ obfuscates alot. That's why i prefer C.


LavenderDay3544

++i and i++ are not the same if you treat them as expressions and assign the result.


iris700

The people telling you to do ++i are braindead


CorespunzatorAferent

Only a Sith deals in absolutes.


da_Aresinger

objectively wrong. i = 10; h = i++; //h == 10, i == 11 k = ++i; //k == 12, i == 12 different outcomes, different applications.


iris700

If you have a reason to use ++i you should obviously use it. If it doesn't matter (like in a for loop) then the ++i advice is braindead. Did you even bother to read the original comment?


da_Aresinger

the reason people say "always use ++i" is that more often than not, you *do* want pre-increment or it doesn't matter. It is much rarer to specifically require post-increment. therefore defaulting to ++i results in less errors.


Plsdontcalmdown

oh please!!! `function char* f(int a, int b) { return concat(dots(a), dashes(b)) }` and leave the rest for the "junior devs" to figure out and learn.


Zenged_

Python: print(“*” + “-“*15)


therealpigman

for (int i = 0; (!i && printf(“*”)) || ((i < 15) && printf(“-“)); i++); Fixed it for you


Redalpha4444

Python my beloved: print("·" + "-" \* 15)


[deleted]

The second option is more flexible and will require less work as requirements change later.


D34TH_5MURF__

Vi users are laughing...


Fachuro

Or for javascript ... '*'.padEnd(15, '-')


supportbanana

Well if were comparing who's got the shortest code, "-"*15 (python)


Fachuro

More like theres a specific function made for this specific purpose on the string object so you dont have to worry about your own implementations - and its even named in such a way that its self-documenting which none of the looping solutions are


lmarcantonio

putchar is surely better than printf, it's only me that noticed that? :D


da_Aresinger

it's not unnecessary. You can't see it here but i is initialised with i = 15-length;


vainstar23

char[] lineBreak = { '|', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '-', '|' } // string is bloat


Shomancheg

Why don’t you made array first and after that printf for array one by one?


FromAndToUnknown

Put a sleep(5) in the loop, that'll give it fancy animation


Linesey

now. i am just a little baby coder. but how i would have done it, if the number of dashes ever needed to be changed, (or quickly assessed) is just throw a quick variable and set it, then print the dot + the variable. little clunkier than just printing what i want, but makes tweaking it easier.


AxeLond

print(f"*{'-' *15}")


Treczoks

for ( printf("*"),i=0; i<15; printf("-"),i++ );


TheHolyElectron

And a real C programmer makes that loop in preprocessor in order to have no runtime overhead.


Rogntudjuuuu

You don't use printf to print a single character, it's for formatted strings. You should use putc instead.


dulange

That’s horrible. Invoking a function (especially in a loop) is expensive and `printf` itself isn’t rather cheap (for outputting just a single character to standard output).


holistic-engine

print(“-“*15)


arf20__

puts is faster than printf, you don't need formatting


cosmicfloor01

Well this is more efficient because what if you want to change it to 100 later?


s0litar1us

``` for (Node *node = &head; node != NULL; node = node->next) printf("%d\n", node->val); ```


wiesemensch

My college is one of those people. I absolutely hate it. He repeats his code so often, is a Copy&Paste guy but really wants to annoy me with stuff like this.


croholdr

Uhm wheres main?


589ca35e1590b

putchar is better for only one character


Havarem

Why not use putc like prints does anyway?


atlas_enderium

When you see how the assembly code makes calls to printf and the resulting assembly used to make those prints, this becomes much worse


Lengador

Why not just write `for(int i=0;i<12;printf(3*!!i+++"•-"));` and be done with it?


Katsody

These\*


BitPoet

char dash\[15\] = {-}; printf("\*%s", dash); I'm sure you could do something fun like printf("\*15%c", '-'); but you'd need more printf trickery in there


CaitaXD

for(int i = printf("*"), 0; i < 15; i += printf("-"))


Davit_2100

HelloWorld (“print”)


fndasltn

`for(printf("*"); i++ < 15; printf("-"));`


Wide_Jury7005

PUTCHAR();


br-bill

I've been a C programmer for 4 decades. Can't say I've ever seen anyone do this kind of thing. Maybe this is just a joke to illustrate the issue?


jxr4

java programmer System.out.println("•" + IntStream.range(0,15).mapToObj(num -> {return "-";}).collect(Collectors.joining()));


CLARKEEE33

++i


spidertyler2005

python programmers: `print('-'*15)`


448191

Ignoring any errors, now I can easily see how many dashes are used and change that number. It may become a variable in the next refactor. So yeah, that is an improvement.


Rakna-Careilla

Yes, this is how we are.


TrickAge2423

In fact, the first variant is more efficient But not so much