Блог пользователя Madiyar

Автор Madiyar, 10 лет назад, По-английски

My another blog hopefully will help to prevent from bugs.

Try to guess the output without using compiler or IDE. Please hide your answers to not spoil.

1.

#include <iostream>
using namespace std;

int main() {
    int a = 020;
    short b = 2;
    cout << a - b << endl;
    return 0;
}

2.

#include <iostream>
using namespace std;

int main() {
    bool ok = true;
    // Try to guess with if condition  \
    if (!ok && true) 
        cout << "I am ok" << endl;
    return 0;
}

3.

#include <iostream>
using namespace std;

int main() {
    unsigned a = 0;
    int b = 2;
    if (a + b >= -2) 
        cout << a + b << ">=" << -2 << endl;
    else
        cout << a + b << "<" << -2 << endl;
    return 0;
}

4.

#include <iostream>
using namespace std;

int main() {
    int  a = 0, b = 1;
    if (a&b==0) {
        cout << (a&b) << "=" << 0 << endl;
    } else {
        cout << (a&b) << "!=" << 0 << endl;
    }
    return 0;
}
  • Проголосовать: нравится
  • +96
  • Проголосовать: не нравится

»
10 лет назад, # |
  Проголосовать: нравится -34 Проголосовать: не нравится

5.

#include <iostream>
using namespace std;

int main() {
    int  a = 17, b = -2;
    cоut << a - - b << endl;
    return 0;
}
»
10 лет назад, # |
  Проголосовать: нравится +15 Проголосовать: не нравится
»
10 лет назад, # |
Rev. 2   Проголосовать: нравится -8 Проголосовать: не нравится

Spoiler

»
10 лет назад, # |
Rev. 2   Проголосовать: нравится +13 Проголосовать: не нравится

Spoiler

»
10 лет назад, # |
Rev. 2   Проголосовать: нравится +16 Проголосовать: не нравится

is it easy question? then just choose the unexpected answer :P

»
10 лет назад, # |
  Проголосовать: нравится +59 Проголосовать: не нравится

Here you can see my set of examples. What do you think about them?

  • »
    »
    10 лет назад, # ^ |
    Rev. 2   Проголосовать: нравится +5 Проголосовать: не нравится

    Cool :) Most of them make sense actually, except #16. Can you explain, please, why it's happening?

    • »
      »
      »
      10 лет назад, # ^ |
      Rev. 4   Проголосовать: нравится +10 Проголосовать: не нравится

      The snippet number 16 invokes undefined behavior. So a question why is not applicable here.

    • »
      »
      »
      10 лет назад, # ^ |
      Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

      OH-MY-GOD. Now I'm trying to remember contests in which I wrote such code... It's such an incredibly insidious bug... It's a very unlucky coincidence of three ingredients:

      • assignment operator evaluates v[0] before f() (I'm not sure if it HAS to be done in this order, but it may),
      • vector has its own capacity (initially it's 1). If you add more elements than it can hold, it allocates more memory somewhere else (and it's usually twice as much memory as before),
      • this way we set the value f() returned to the memory where v[0] was before executing f(). It triggers the undefined behaviour (and in this case "nothing" happens).

      For example you can notice that if you have 1 or 2 or 4 elements initially in vector, the whole thing gets screwed up, but having 3 or 5 elements "works" perfectly (there was no need to reallocate the vector). IT'S INSANE...

  • »
    »
    10 лет назад, # ^ |
    Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

    interesting :))

    another version for problem 2:

    #include <iostream>
    using namespace std;
    int main(){
        int n;
        cin >> n; // input 60
        int a = 1 << n;
        cout << a << endl;
        return 0;
    }
    

    I'm wondering why their behaviors are different!

    I'd like to know the explanation for problem 1, what does 2[a][b] refer to?

    • »
      »
      »
      10 лет назад, # ^ |
      Rev. 6   Проголосовать: нравится +3 Проголосовать: не нравится

      2[a][b] is a shorten of *(*(2+a)+b) and equivalent to b[a[2]].

      You can always assume x[y] is same as *(x+y) and y[x]. But it's not suggested to code like 10[a] because only some programmers coding in assembly language will like that!

      Correct: in C++ some x[y] is operator [] of typeof(x). They're not equivalent with *(x+y) or y[x]. For example, if x is a vector.

    • »
      »
      »
      10 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      Anyway, behavior is undefined in this case. I think, if disable optimizations, they will both output 228. With enabled optimizations, compiler probably tries to inline this constant and make it in different way.

  • »
    »
    9 лет назад, # ^ |
      Проголосовать: нравится +6 Проголосовать: не нравится

    18 is impossibly evil

»
10 лет назад, # |
Rev. 4   Проголосовать: нравится -11 Проголосовать: не нравится

deleted

»
10 лет назад, # |
Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

Spoiler.

»
10 лет назад, # |
  Проголосовать: нравится +13 Проголосовать: не нравится

One more:

#include <iostream>
using namespace std;

int main() {
	int a = 228, b = 322;
	cout << (a == b) ? 228 : 322;
}
  • »
    »
    10 лет назад, # ^ |
      Проголосовать: нравится +17 Проголосовать: не нравится

    Nice example (had to compile to understand) but

    g++ a.cpp 2>&1| pbcopy  
    
    a.cpp:6:21: warning: operator '?:' has lower precedence than '<<'; '<<' will be evaluated first [-Wparentheses]
                            cout << (a == b) ? 228 : 322;
                            ~~~~~~~~~~~~~~~~ ^
    a.cpp:6:21: note: place parentheses around the '<<' expression to silence this warning
                            cout << (a == b) ? 228 : 322;
                                             ^
                            (               )
    a.cpp:6:21: note: place parentheses around the '?:' expression to evaluate it first
                            cout << (a == b) ? 228 : 322;
                                             ^
                                    (                   )
    a.cpp:6:23: warning: expression result unused [-Wunused-value]
                            cout << (a == b) ? 228 : 322;
                                               ^~~
    2 warnings generated.
    
    
»
10 лет назад, # |
  Проголосовать: нравится +21 Проголосовать: не нравится

Another one

#include <iostream>
using namespace std;
 
int main() {
    long long a = 1e18 + 1;
    cout << a << endl; 
    return 0;
}
  • »
    »
    10 лет назад, # ^ |
      Проголосовать: нравится +38 Проголосовать: не нравится

    Why everybody downvoting? Try to compile and run.

    Output is : 10^18 not 10^18+1.

    Is this because of the double representation?

  • »
    »
    10 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    Funny example. I'll add it to collection?

    • »
      »
      »
      10 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      Of course, yes. And, please, fix 11 example. Probably it has encoding problems. My browser shows ??/ instead of backslashes.

  • »
    »
    9 лет назад, # ^ |
      Проголосовать: нравится -50 Проголосовать: не нравится

    I'd like to add one then!

    #include <iostream>
    #include <cmath>
    using namespace std;
     
    int main() {
        int a = pow(5,4);
        cout << a << endl; 
        return 0;
    }
    
»
9 лет назад, # |
  Проголосовать: нравится -13 Проголосовать: не нравится

What is the output of the following program?

#include <iostream>

int main()
{
	int a = 0;
	int b = 0;

	// Iterate 3 times
	for (size_t i = 1; i <= 3 || a * b < 10; i++)
	{
		int mult = 9000 * i;

		a += mult;
		b += mult;

		if (a == b)
		{
			std::cout << "Good" << std::endl;
		}
		else
		{
			std::cout << "Bad" << std::endl;
			break;
		}
	}
}
»
9 лет назад, # |
  Проголосовать: нравится -39 Проголосовать: не нравится

Nice bugs!

Here is one more

#include<bits/stdc++.h>
using namespace std;
void swap(int a,int b)
{
    int t;
    t=a;
    a=b;
    b=t;
}
int main()
{
    int x=5,y=2;
    swap(x,y);
    cout<<x<<" "<<y;
}

  • »
    »
    9 лет назад, # ^ |
      Проголосовать: нравится -34 Проголосовать: не нравится

    Above bug can be prevented by using own C++ swap function.

    This is one of my most hated bugs.

    #include<bits/stdc++.h>
    using namespace std;
    int main()
    {
        int x=12;
        if(x/5==2.4) cout<<"Number is 12";
        else cout<<"Number is NOT 12";
    }
    
    
    • »
      »
      »
      9 лет назад, # ^ |
      Rev. 2   Проголосовать: нравится +2 Проголосовать: не нравится

      It's not bug. And I think it will be more weird if (int) / (int) = (double).

      • »
        »
        »
        »
        9 лет назад, # ^ |
          Проголосовать: нравится -13 Проголосовать: не нравится

        No, it's a bug... But it's user-made bug, not compiler's one (it's about your link)

        It's most frequently made by n00bs, and those, who use duck-typing languages, like Python, in their day-to-day work — http://ideone.com/R903zc

    • »
      »
      »
      9 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      Above bug can be prevented by using own C++ swap function.

      This is not a bug that function doesn't change outside variables, when you pass them by value. Use references:

      void swap(int &a, int &b)
      
»
9 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

After giving all of them a try and referring this:

I still don't get the first one. Why is 020 considered in octal? I didn't get the 3rd one either. Any help?

I did the other 2 correct. Second one was easy (and smart too). For fourth, I suppose that most people assume brackets while reading (They read it something like this : if ((a&b)==0) : although they are careful while writing) and hence must have processed the if part, instead of else! Am I right?

  • »
    »
    9 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    You can use numbers in base 8 (octal) by writing their octal representation preceded by a zero. So, 020 is equal to 20(octal)=16(dec), 02731 is equal to 2731(octal)=1497(dec), etc.

    • »
      »
      »
      9 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      Thanks for the help. I get it now. But I'm still not sure where would this trick be useful? Any help regarding that?

      • »
        »
        »
        »
        9 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится

        You're welcome :)

        I have only used this trick in simple base conversion problems. Didn't actually need it in algorithmic problems until today.

      • »
        »
        »
        »
        9 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится

        If you use bitwise operations (this is a rare thing, but still is useful in some real-life problems like coding a chess engine and sometimes in competitive programming), it is more convenient to work with power2-based systems, because you need to know binary representation just looking at number. For example, it is easy to see that hexadecimal 123 (0x123 in C++, Python and most other languages) is the same as binary 0001 0010 0011 and also equals octal 443 (100 100 011). It is not so obvious, however, that decimal 291 is the same.

        And the binary system itself can be inconvenient to work with directly because of length of numbers.

»
8 лет назад, # |
  Проголосовать: нравится -26 Проголосовать: не нравится

hi please i have a runtime error on test 1 with this code any help???

package graph.party;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;
public class Party {
	public static void main(String[] args) {
		
		Scanner in = new Scanner(System.in);
		System.out.println("entrez le nombre des employés\n");
		int n = in.nextInt();
		ArrayList<Integer> tab=new ArrayList<Integer>(n);
		int i=0;
		while(i<n){
       		tab.add(in.nextInt());
       		i++;
		}
		Set<Integer> mySet = new HashSet<Integer>(tab);
		tab.clear();
	tab=new ArrayList<Integer>(mySet);
		System.out.println(tab.size());

	}

}

»
8 лет назад, # |
Rev. 4   Проголосовать: нравится +11 Проголосовать: не нравится

In 2008, I learned C language by solving these tricky puzzles:

http://www.gowrikumar.com/c/index.php

After so many years, I still don't see a better collection of C language puzzles.

Example from the page:

The following is a piece of C code, whose intention was to print a minus sign 20 times. But you can notice that, it doesn't work.

  #include <stdio.h>
  int main()
  {
      int i;
      int n = 20;
      for( i = 0; i < n; i-- )
          printf("-");
      return 0;
  }

Well fixing the above code is straight-forward. To make the problem interesting, you have to fix the above code, by changing exactly one character. There are three known solutions. See if you can get all those three.