可以放置多少个星号?
#c #gcc #clang

在C和C ++中,使用Asterisk(*)来声明或取消指针变量。

顺便说一句,您是否知道可以将函数调用带有最多的星号?

这是简单且有效的C程序。

#include <stdio.h>

int main(){
  printf("Hello world!\n");
}

这也是有效的C程序。

#include <stdio.h>

int main(){
  (*printf)("Hello world!\n");
}

这也是有效的。

#include <stdio.h>

int main(){
  (******printf)("Hello world!\n");
}

这个带有100个星号的程序也是一个完美的C程序。

#include <stdio.h>

int main(){
  (
   **********
   **********
   **********
   **********
   **********
   **********
   **********
   **********
   **********
   **********
   printf)("Hello world!\n");
}

您看到了这个,您想知道可以添加多少个星号?让我们找出答案。

这是一个红宝石脚本,可预先为printf函数提供指定的星号。

def check(n)
  s = "*"*n
  open("test.c","w") do |f|
  f.puts <<EOS
#include <stdio.h>
int main(){
(#{s}printf)("Hello World!\\n");
}
EOS
end
  return system("clang test.c")
end

check(ARGV[0].to_i)

您可以这样使用。

ruby check.rb 10

它将生成以下源代码。

#include <stdio.h>
int main(){
(**********printf)("Hello World!\n");
}

让我们用一千个星号尝试一下。

ruby check.rb 1000

没问题。然后尝试一万。

ruby check.rb 10000
PLEASE submit a bug report to https://bugs.llvm.org/ and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
(snip)
clang-12: error: unable to execute command: Segmentation fault (core dumped)
clang-12: error: clang frontend command failed due to signal (use -v to see invocation)

clang死于sigsegv。

clang可以使用1000个星号,死于10,000个星号。因此,那里的某个地方必须有一个限制。让我们通过二进制搜索检查一下。

def check(n)
  s = "*"*n
  open("test.c","w") do |f|
  f.puts <<EOS
#include <stdio.h>
int main(){
(#{s}printf)("Hello World!\\n");
}
EOS
end
  if system("clang test.c 2> /dev/null")
    puts "#{n} OK"
    false
  else
    puts "#{n} NG"
    true
  end
end

(1000..10000).bsearch do |n|
  check(n)
end

这是执行结果。

$ ruby search.rb
5500 NG
3250 NG
2125 NG
1562 OK
1844 NG
1703 NG
1633 OK
1668 NG
1651 OK
1660 NG
1656 OK
1658 NG
1657 OK

现在,我们有了新的知识。我们最多可以放置1657年的星号(环境依赖)。

顺便说一句,让我们尝试使用GCC。这是一个检查脚本。

def check(n)
  s = "*"*n
  open("test.c","w") do |f|
  f.puts <<EOS
#include <stdio.h>
int main(){
(#{s}printf)("Hello World!\\n");
}
EOS
end
  return system("gcc test.c")
end

check(ARGV[0].to_i)

让我们尝试1000。

ruby check_gcc.rb 1000

没问题。接下来,10,000。

ruby check_gcc.rb 10000

好吧,大约有100,000个?

ruby check_gcc.rb 100000

认真吗?然后,1,000,000。

$ ruby check_gcc.rb 1000000
gcc: internal compiler error: Segmentation fault signal terminated program cc1
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://bugzilla.redhat.com/bugzilla> for instructions.

糟糕,GCC使用了一百万个星号。

所以,如果您想使用一万个星号,请使用gcc。