C++ for循环的条件仅在命中断点后生效

C++ for循环的条件仅在命中断点后生效,c++,gdb,C++,Gdb,我正试图解决hackerrank的一个问题 目前我的代码是错误的,但这不是问题的重点。 问题在于for循环,其条件似乎并不总是有效。 代码如下: #include <cassert> #include <iostream> #include <set> using namespace std; // Integer power. long ipow(int x, int y) { assert(x > 0); assert(y >

我正试图解决hackerrank的一个问题

目前我的代码是错误的,但这不是问题的重点。 问题在于
for
循环,其条件似乎并不总是有效。 代码如下:

#include <cassert>
#include <iostream>
#include <set>

using namespace std;

// Integer power.
long ipow(int x, int y)
{
    assert(x > 0);
    assert(y >= 0);

    long res = 1;
    while (y--)
        res *= x;
    return res;
}

std::set<int> compute_distinct_sequence_numbers(int n, int s, int p, int q)
{
    static_assert(sizeof(long) > 4, "long is assumed to be larger 4 bytes");

    set<int> distinct_numbers;
    const long max1 = ipow(2, 31);  // maximum plus 1

    // Compute first number of sequence.
    int prev = s % max1;
    distinct_numbers.emplace(prev);

    // Compute subsequent elements of sequence and put them in set.
    for (int i = 1; i < n; ++i) {
        prev = (prev * p + q) % max1;
        distinct_numbers.emplace(prev);
    }

    return distinct_numbers;
}

int main(int argc, char** argv)
{
    // Read numbers.
    int n, s, p, q;
    if (!(cin >> n >> s >> p >> q))
        throw std::runtime_error("error on input");;

    // Compute set containing distinct number of sequence.
    std::set<int> distinct_numbers = compute_distinct_sequence_numbers(n, s, p, q);

    // Print number of distinct numbers in sequence.
    cout << distinct_numbers.size() << std::endl;

    return 0;
} 
我在该行上设置了一个条件断点(
I==n
prev=(prev*p+q)%max1。
通常不可能命中此断点,因为循环应该在命中
n
之前退出。 即使我对条件断点使用了更高的值(如
I==2*n
),也会命中断点

一旦我到达断点,程序立即退出循环。这适用于单步执行(GDB命令
n
)和连续执行(GDB命令
c

这是我的超级简单Makefile:

CC = g++
CFLAGS = -Wall -std=c++14 -c -g
LDFLAGS = 

all:    main

main:   main.o
        $(CC) $(LDFLAGS) main.o -o main

main.o: main.cpp
        $(CC) $(CFLAGS) main.cpp
该程序在Ubuntu 16.04上运行

我做错了什么? 在GDB中运行时,程序的行为如何不同? 这似乎简单得令人尴尬

一旦我到达断点,程序立即退出循环

这是一个例子。正如Mark Plotnick所注意到的,断点条件不仅仅是一个条件,而是一个条件和一个赋值

每次评估条件时,
i
都会被分配值
n
,然后根据0评估结果

这意味着在调试器下,当这个特定的“条件”断点就位时,循环只执行一次

现在,当我根本不连接GDB时,我观察到:

$ g++ -g t.cc -O0 &&  echo "10000000 658061970 695098531 1430548937" | time ./a.out
10000000
18.15user 0.20system 0:18.36elapsed 99%CPU (0avgtext+0avgdata 472032maxresident)k
0inputs+0outputs (0major+117322minor)pagefaults 0swaps

$ g++ -g t.cc -O2 &&  echo "10000000 658061970 695098531 1430548937" | time ./a.out
10000000
12.09user 0.14system 0:12.27elapsed 99%CPU (0avgtext+0avgdata 472028maxresident)k
0inputs+0outputs (0major+117322minor)pagefaults 0swaps
从中我们可以得出结论,程序之所以慢,是因为它执行了1000万次迭代,而不是因为
for
循环不知何故被破坏了

使用
perf record
perf report
,我们可以看到这些时间都花在了什么地方:

# Samples: 50K of event 'cycles:uppp'
# Event count (approx.): 50290745010
#
# Overhead  Command  Shared Object        Symbol                                                                                                         
# ........  .......  ...................  ...............................................................................................................
#
    79.02%  a.out    a.out                [.] std::_Rb_tree<int, int, std::_Identity<int>, std::less<int>, std::allocator<int> >::_M_emplace_unique<int&>
     8.75%  a.out    a.out                [.] std::_Rb_tree<int, int, std::_Identity<int>, std::less<int>, std::allocator<int> >::_M_erase
     5.82%  a.out    libstdc++.so.6.0.25  [.] std::_Rb_tree_insert_and_rebalance
     0.93%  a.out    libstdc++.so.6.0.25  [.] 0x00000000000a9440
     0.89%  a.out    libc-2.28.so         [.] _int_malloc
     0.86%  a.out    libc-2.28.so         [.] cfree@GLIBC_2.2.5
     0.81%  a.out    a.out                [.] compute_distinct_sequence_numbers
     0.78%  a.out    libc-2.28.so         [.] _int_free
#样本:50K个事件“周期:uppp”
#事件计数(大约):50290745010
#
#开销命令共享对象符号
# ........  .......  ...................  ...............................................................................................................
#
79.02%a.out a.out[.]标准:_Rb_tree:_M_emplace_unique
8.75%a.out a.out[.]标准:_Rb_树:_M_擦除
5.82%a.out libstdc++.so.6.0.25[.]标准:_Rb_tree_insert_和_rebalance
0.93%a.out libstdc++.so.6.0.25[.]0x00000000000a9440
0.89%a.out libc-2.28.so[.]\u int\u malloc
0.86%a.out libc-2.28.so[.]cfree@GLIBC_2.2.5
0.81%a.out a.out[.]计算不同的序列号
0.78%不含libc-2.28.so[.].\u不含

可能是整数溢出吗?尝试将所有的
int
类型更改为
long
类型(您有一个断言'long`>4字节,但从不使用
long
信息断点
表示
仅当i=n
时停止。这是打字错误吗?我希望它是
仅当i==n
时停止
# Samples: 50K of event 'cycles:uppp'
# Event count (approx.): 50290745010
#
# Overhead  Command  Shared Object        Symbol                                                                                                         
# ........  .......  ...................  ...............................................................................................................
#
    79.02%  a.out    a.out                [.] std::_Rb_tree<int, int, std::_Identity<int>, std::less<int>, std::allocator<int> >::_M_emplace_unique<int&>
     8.75%  a.out    a.out                [.] std::_Rb_tree<int, int, std::_Identity<int>, std::less<int>, std::allocator<int> >::_M_erase
     5.82%  a.out    libstdc++.so.6.0.25  [.] std::_Rb_tree_insert_and_rebalance
     0.93%  a.out    libstdc++.so.6.0.25  [.] 0x00000000000a9440
     0.89%  a.out    libc-2.28.so         [.] _int_malloc
     0.86%  a.out    libc-2.28.so         [.] cfree@GLIBC_2.2.5
     0.81%  a.out    a.out                [.] compute_distinct_sequence_numbers
     0.78%  a.out    libc-2.28.so         [.] _int_free