Использование свойства массива Push in object [duplicate]

Что такое «неопределенный ссылочный / неразрешенный внешний символ»

Я попытаюсь объяснить, что такое «неопределенный ссылочный / неразрешенный внешний символ».

note : я использую g ++ и Linux, и все примеры для него

Например, у нас есть некоторый код

// src1.cpp
void print();

static int local_var_name; // 'static' makes variable not visible for other modules
int global_var_name = 123;

int main()
{
    print();
    return 0;
}

и

// src2.cpp
extern "C" int printf (const char*, ...);

extern int global_var_name;
//extern int local_var_name;

void print ()
{
    // printf("%d%d\n", global_var_name, local_var_name);
    printf("%d\n", global_var_name);
}

Создание объектных файлов

$ g++ -c src1.cpp -o src1.o
$ g++ -c src2.cpp -o src2.o

После фазы ассемблера у нас есть объектный файл, который содержит любые экспортируемые символы. Посмотрите на символы

$ readelf --symbols src1.o
  Num:    Value          Size Type    Bind   Vis      Ndx Name
     5: 0000000000000000     4 OBJECT  LOCAL  DEFAULT    4 _ZL14local_var_name # [1]
     9: 0000000000000000     4 OBJECT  GLOBAL DEFAULT    3 global_var_name     # [2]

Я отклонил некоторые строки из вывода, потому что они не имеют значения

Итак, мы видим следующие символы для экспорта.

[1] - this is our static (local) variable (important - Bind has a type "LOCAL")
[2] - this is our global variable

src2.cpp ничего не экспортирует, и мы не видели его символов

Свяжите наши объектные файлы

$ g++ src1.o src2.o -o prog

и запустите его

$ ./prog
123

Linker видит экспортированные символы и связывает их. Теперь мы пытаемся раскомментировать строки в src2.cpp, как здесь

// src2.cpp
extern "C" int printf (const char*, ...);

extern int global_var_name;
extern int local_var_name;

void print ()
{
    printf("%d%d\n", global_var_name, local_var_name);
}

, и перестроить объектный файл

$ g++ -c src2.cpp -o src2.o

OK (нет ошибок), потому что мы только строим объектный файл, связь еще не завершена. Попробуйте установить ссылку

$ g++ src1.o src2.o -o prog
src2.o: In function `print()':
src2.cpp:(.text+0x6): undefined reference to `local_var_name'
collect2: error: ld returned 1 exit status

Это произошло потому, что наше local_var_name статично, то есть оно не отображается для других модулей. Теперь глубже. Получить выход фазы перевода

$ g++ -S src1.cpp -o src1.s

// src1.s
look src1.s

    .file   "src1.cpp"
    .local  _ZL14local_var_name
    .comm   _ZL14local_var_name,4,4
    .globl  global_var_name
    .data
    .align 4
    .type   global_var_name, @object
    .size   global_var_name, 4
global_var_name:
    .long   123
    .text
    .globl  main
    .type   main, @function
main:
; assembler code, not interesting for us
.LFE0:
    .size   main, .-main
    .ident  "GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2"
    .section    .note.GNU-stack,"",@progbits

Итак, мы видели, что для local_var_name нет метки, поэтому линкер не нашел его. Но мы хакеры :), и мы можем это исправить. Откройте src1.s в текстовом редакторе и измените

.local  _ZL14local_var_name
.comm   _ZL14local_var_name,4,4

на

    .globl  local_var_name
    .data
    .align 4
    .type   local_var_name, @object
    .size   local_var_name, 4
local_var_name:
    .long   456789

i.e. вам должно быть как ниже

    .file   "src1.cpp"
    .globl  local_var_name
    .data
    .align 4
    .type   local_var_name, @object
    .size   local_var_name, 4
local_var_name:
    .long   456789
    .globl  global_var_name
    .align 4
    .type   global_var_name, @object
    .size   global_var_name, 4
global_var_name:
    .long   123
    .text
    .globl  main
    .type   main, @function
main:
; ...

мы изменили видимость local_var_name и установили его значение в 456789. Попробуйте построить из него объектный файл

$ g++ -c src1.s -o src2.o

ok, см.

$ readelf --symbols src1.o
8: 0000000000000000     4 OBJECT  GLOBAL DEFAULT    3 local_var_name

В настоящее время local_var_name имеет привязку GLOBAL (LOCAL)

link

$ g++ src1.o src2.o -o prog

и запускает ее

$ ./prog 
123456789

ok, мы взломаем его:)

Итак, в результате - «неопределенная ссылка / неразрешенная внешняя ошибка символа» происходит, когда компоновщик не может найти глобальные символы в объектных файлах.

23
задан kevinius 31 October 2013 в 15:34
поделиться

4 ответа

Я закончил построение метода forEach и хотел поделиться этой диаграммой со всеми, надеюсь, что это поможет кому-то еще понять его внутреннюю работу.

The forEach method [/g0]

8
ответ дан kevinius 3 September 2018 в 14:02
поделиться

Если вы не передадите второй параметр в forEach, this укажет на глобальный объект. Для достижения того, что вы пытались сделать

var jow = [5, 10, 45, 67];

jow.forEach(function(v, i, a) {
    a[i] = v + 1;
});

console.log(jow);

Выход

[ 6, 11, 46, 68 ]
3
ответ дан thefourtheye 3 September 2018 в 14:02
поделиться

Состояние MDN:

array.forEach (callback [, thisArg])

Если параметр thisArg предоставляется для каждого элемента, он будет использоваться в качестве этого значения для каждого вызова обратного вызова, как если бы вызывался callback.call (thisArg, element, index, array). Если thisArg не определено или null, это значение внутри функции зависит от того, находится ли функция в строгом режиме или нет (передано значение, если в строгом режиме, глобальный объект, если в нестрогом режиме).

Короче говоря, если вы предоставляете только обратный вызов, и вы находитесь в нестрогом режиме (случай, который вы представили), это будет глобальный объект (окно).

https : //developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach

36
ответ дан Tibos 3 September 2018 в 14:02
поделиться

Внутри forEach, this относится к глобальному объекту window. Это так, даже если вы вызываете его из другого объекта (т. Е. Того, который вы создали)

window.foo = 'window';

var MyObj = function(){
  this.foo = 'object';
};

MyObj.prototype.itirate = function () {
  var _this = this;

  [''].forEach(function(val, index, arr){
    console.log('this: ' + this.foo); // logs 'window'
    console.log('_this: ' + _this.foo); // logs 'object'
  });
};

var newObj = new MyObj();

newObj.itirate();
// this: window
// _this: object
3
ответ дан vladvlad 3 September 2018 в 14:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: