37

Bob, a C programmer and a believer of printf-debugging, gets hired by a failing software company. The company is not doing well because they adopt an archaic source code management system which does not allow any modification to any lines of code once they are checked in.

As you can imagine, poor Bob is too excited at resolving a bug with his printf debugging technique and accidentally checked in that line of C code:

printf("OK, bug gone - this should make my nasty boss happy");

Now, he desperately wants to silence it. But the stupid system won't allow him to edit that line. He can only add new lines of code around it to cancel its effect. There are many ways to achieve that, but can you find the one which adds the fewest lines, with the fewest characters?

Rubio
  • 41,676
  • 6
  • 90
  • 242
  • 13
    Is this actually something that just happened to you? – Dr Xorile Jun 23 '16 at 22:06
  • 12
    Lol I haven't seen such crappy version control system in real life yet –  Jun 23 '16 at 22:22
  • All three 3-char solutions so far, including mine, give compile-time warnings but do result in working executables – humn Jun 23 '16 at 22:36
  • 1
    @humn I haven't tested for warnings, but you may well be right. It'll be awesome if you can find something no longer than 3-char buy triggers no warnings :) –  Jun 23 '16 at 22:41
  • Next puzzle: How to reactivate that printf() because the crappy VCS has made the file so large that the crappy file system won't allow the file to grow enough to accommodate a new copy of the line. (Ps. gotta love that you haven't seen such a crappy system "yet.") – humn Jun 23 '16 at 23:04
  • @humn lol is there a solution to this deadlock –  Jun 23 '16 at 23:06
  • 25
    Just add £ in any line. The system will fail to compile, the code line can not be changed. The company is out of bussiness and the printf will never ever be executed again.... (I chose £ on purpose, becuse it is going to be an obsolete character soon... 8-[ ) – BmyGuest Jun 24 '16 at 07:07
  • 2
    @BmyGuest, I think you've got that the wrong way around unless you think the repercussions of "Brexit" are so severe that they'll make the UK completely stop existing. It's less likely to switch to using the euro now (though it was never very likely to), so the continued existence of the pound is more likely, not less. – Gareth McCaughan Jun 24 '16 at 12:18
  • 9
    This might fit better over at CodeGolf. – Engineer Toast Jun 24 '16 at 12:19
  • 3
    Too easy for CodeGolf, I think :-). – Gareth McCaughan Jun 24 '16 at 12:20
  • 5
    This is definitely [tag:code-golf] and should belong there. – noɥʇʎԀʎzɐɹƆ Jun 24 '16 at 16:03
  • 1
    Yeah, but this is language specific and the golfers might not like that –  Jun 24 '16 at 16:08
  • 1
    @uoɥʇʎPʎzɐɹC It's whatever the OP decides it to be. In current form, not applicable at CG – Insane Jun 24 '16 at 17:32
  • 3
    I've been lurking in this SE-P site for a while and only added it a short time ago for another one I liked... I think this is my only second ever only comment, and that's because: awesome puzzle concept. Plain, simple, functional even if not ever really practical, and because I like the answers! – Madivad Jun 26 '16 at 02:13
  • 1
    The story must be told, what was the inspiration for this puzzle? – humn Jun 26 '16 at 21:44
  • 1
    Don't be like Bob, leave the company! – CinCout Jun 27 '16 at 04:53
  • 1
    @CinCout My point is: a believer of printf debugging deserves a company with dysfunctional VCS :) –  Jun 27 '16 at 13:49

14 Answers14

53

Works in gcc, with 3 characters on the line above:

//\   (same-line comment + line continuation)

Side note:   To reactivate the printf() add a blank line above it.

//\

printf("OK, bug gone - this should make my nasty boss happy");

Another side note:   As learned from an answer to ‘‘Loopy’’ C loop, with 5 characters this approach can really puzzle that nasty boss by using, what else, ??.

//??/
  ( ??/ is a trigraph that translates to \ in service of an obsolete text-encoding system from the same era, no doubt, as the source code management system in question. )

Gag variation, 1 character total, no new line: (not allowed, appends to an existing line)

\
(added to the end of the previous line, if that line happens to already have a “//...” comment)

humn
  • 21,899
  • 4
  • 60
  • 161
  • 17
    This makes me uncomfortable. – Will Jun 23 '16 at 22:11
  • 1
    The gag version makes me more uncomfortable :p –  Jun 23 '16 at 22:57
  • 1
    the gag variation would be even funnier if the line before the print statement would have been a highly used macro :D – hoffmale Jun 26 '16 at 13:49
  • 1
    the question states "shortest". not fastest. + this is better by utilizing the pre processor... so the bin doesnt even have the bad code. – Tomer W Jun 26 '16 at 15:22
  • @TomerW:  (1) Interesting point, but are you sure?  I believe that comments are not handled by the preprocessor.  (2) With the accepted answer, any decent compiler will see that the new code is testing a constant, and that the printf can never be executed, and accordingly it will not generate the “dead code”. – Peregrine Rook Jun 26 '16 at 18:14
50

Well, he can do it by adding

if(0)

on the line before. So that's

one extra line, five extra characters.

Or, slightly better, exploit the fact that

printf returns a value

and make that first line

0&&

for

one line, three characters.

Gareth McCaughan
  • 119,120
  • 7
  • 313
  • 454
24

How about

/* before and */ after

2 lines, 4 characters.

gtwebb
  • 3,626
  • 16
  • 24
20

Assume that's not the first time Bob had that problem, therefore he added on a central include.

extern int gshow_me; // initialized with 0 in c file
#define _ if(gshow_me)
#define _x gshow_me^=1;
#define _0 gshow_me=0;

Then he just adds a line containing a single _ before (one line one char), like:

_
printf("OK, bug gone - this should make my nasty boss happy");

To recover the text add _x before the _ line and _0 after the printf-line, like:

_x
_
printf("OK, bug gone - this should make my nasty boss happy");
_0

Using the int variable the compiler doesn't complain for constant condition. _x inverts the meaning of _, so it can be reenabled.

Adding more _x in front toggles printing on and off.

Though .. the crappy file system won't allow to store the additional cvs data, so the filesystem problem cannot be resolved.

lexx9999
  • 309
  • 1
  • 3
  • 2
    Vote of approval for minimal marginal cost, for built-in reversibility, for showing the solution in place and for no compile-time warnings. Not crappy at all! – humn Jun 24 '16 at 02:05
  • I'd been thinking that he'd meant to use dprintf which he'd defined elsewhere as a macro that could etiher chain to "printf" or a do-nothing function. Fortunately, since he doesn't believe in indenting, that would allow him to use d\ on the line preceding the printf. – supercat Jun 24 '16 at 22:19
  • 1
    I liked this question so much, I was about to re-ask it in a reversal scenario, that for whatever reason, you needed the line back, and you've not only answered the original question, but added the reversal as well. Great stuff. And now it just means I have to come up with my own original idea lol – Madivad Jun 26 '16 at 02:15
  • Why are you using ^=1?  (I know what it does; I'm asking why you use it rather than just _0 and _1.)  This way, if this is in a loop, the code (the printf) will execute on the first iteration and no others.   (Unless the definition for _0 is a typo, and you meant for it to do what its name implies.) – Peregrine Rook Jun 26 '16 at 19:43
  • @peregrine Indeed, there was a typo #define _0 gshow_me=1; was wrong, fixed it. _x is for toggling on/off. – lexx9999 Jun 26 '16 at 19:51
  • @peregrine, just 0 / _1 would do it also, would just look different. ` pthen_1 _ p _0then_1 _0 _ p _0` – lexx9999 Jun 26 '16 at 19:58
  • Yes, as I said, I understand how it works, and I know that _0 and _1 would have been enough. Also, arguably, _x is sufficient unto itself, and you don't need _0. – Peregrine Rook Jun 26 '16 at 20:02
  • @PeregrineRook I see you point, but I wanted to avoid having to add pairs of _x _x _ p _0 then _x _x _ p **_0** without _0: _x _ p _x then _x _x _ p **_x _x** the last two _x fold into a single _0. – lexx9999 Jun 26 '16 at 20:07
13

Using a GNU language extension, 3 characters on the line before:

1?:

Explanation

Null coalescing operator - https://en.wikipedia.org/wiki/%3F:#C

niemiro
  • 530
  • 2
  • 12
11

some solutions not yet (explicitly) mentioned

1 line, 3 chars:

1||
printf("OK, bug gone - this should make my nasty boss happy");

2 lines, 5 chars:

[]{
printf("OK, bug gone - this should make my nasty boss happy");
};

2 lines, 9 chars:

goto m;
printf("OK, bug gone - this should make my nasty boss happy");
m:

The following solutions don't have to be directly before the printf line, so they might be harder to detect.

1 line, 15 chars: (nasty!)

fclose(stdout);
printf("OK, bug gone - this should make my nasty boss happy");

1 line, 24 chars (also nasty):

auto printf=[](char*){};
printf("OK, bug gone - this should make my nasty boss happy");


Also, I tried variants of this (1 line, 2 chars) but it breaks on not having enough arguments :( Maybe there's some variation of printf that I'm missing? (note that this requires no indenting on the line with the printf statement)

s\
printf("OK, bug gone - this should make my nasty boss happy");

hoffmale
  • 277
  • 2
  • 6
  • 1
    o.O 10 upvotes and nobody pointed out that technically, 2 of the solutions are c++ only (c++11 or higher) – hoffmale Jun 26 '16 at 22:41
  • 2
    The nasty ones break the entire application, especially the fclose one. – orion Jun 27 '16 at 14:29
  • That why I marked them as nasty :) Well, the second one (the c++ one) can be scoped, so depending on its position it might only break the relevant function, not the whole program. – hoffmale Jun 27 '16 at 19:59
10

Bob could place

if(0)

above the line

Gareth McCaughan
  • 119,120
  • 7
  • 313
  • 454
Qfwfq
  • 304
  • 1
  • 4
8

This one will depend on the compiler. Some compilers may accept it, others won't. But it's only two characters :-)

#\ which turns the printf into an illegal preprocessor line, which may or may not be ignored.

ABcDexter
  • 7,262
  • 4
  • 42
  • 84
gnasher729
  • 776
  • 3
  • 6
7

One line before, four characters:

1?0:

niemiro
  • 530
  • 2
  • 12
  • 1
    This and its abbreviated companion are especially good because they work even if printf doesn't return a value, unlike Gareth McCaughan's three-character answer. – Peregrine Rook Jun 26 '16 at 19:32
7

While that line may be valid in C, it is also a valid line in many other languages, such as Brainfuck. Brainfuck will only interpret the comma as asking for input, and will treat the rest of the characters as a comment. Bob was working in a Brainfuck interpreter instead of a C one. Bob needs to add no new lines.

Obviously this isn't the intended solution, but I just wanted to add some .

user25629
  • 87
  • 1
  • Seriously?  A comma in a *string* argument to a printf turns the remainder of the string into a *comment?*  That's one f***ed up language!    :-)    I gotta go and learn me that language … … … *NOT!* – Peregrine Rook Jun 26 '16 at 19:49
  • 1
    How is this an answer ? –  Jun 27 '16 at 18:41
5

Because Bob is a C programmer he knows all about memory and decides to:

memcpy(&"OK, bug gone - this should make my nasty boss happy", &"\0", 1); // copy a null character to the start of the string in the static memory segment

which would probably:

Cause a segmentation fault (compiler / system dependant). If not, then the printf will print nothing, and the new code could be hidden somewhere else in the program (before execution of the printf).

1 line, 73 characters

QuantumKarl
  • 151
  • 2
3

Another possible answer is:

#ifdef DEBUG
printf("OK, bug gone - this should make my nasty boss happy");
#endif

If the

macro is defined i.e. we have a #define DEBUG something

Then

the printfstatement will be printed, else nothing.

Note:

These(the macros) are used in online judges.

wovano
  • 103
  • 5
ABcDexter
  • 7,262
  • 4
  • 42
  • 84
  • 2
    Unless you really want to make it a conditional (which is out of the scope of this question), you could reduce the character count by using #if 0. – Peregrine Rook Jun 26 '16 at 20:30
2

He can simple add following line after printf:

printf("\r");

Or can add following line above

1?0:

  • 4
    On my system, printing \r returns the caret back to the start of the line, but keeps the contents. E.g. the final output of printf("aaaa\rbb") would be bbaa. – Kroltan Jun 24 '16 at 14:36
  • 1
    And the second answer was suggested over eight hours ago.  After you think of an answer, you should read all the other answers that have already been posted (yes, I know; the spoiler markdown makes it such a pain; it takes *forever!*    :-)    ) and, if somebody else has already posted your idea, and you aren't improving on it, then don't.  Just keep your hands where we can see them, and walk away.     :-)    ⁠ – Peregrine Rook Jun 26 '16 at 19:58
2

He can add the following line of code

1/0;

On the line before.

1 line of code, 4 characters

Also,

This code will cause the system to crash, but no such restriction was given so... Yay?

user64742
  • 1,204
  • 8
  • 22
  • 3
    I guess thia will cause his nasty boss to order him to debug, which will create more printf problems lol –  Jun 27 '16 at 13:47