C2440 ошибка c

Одной из самых распространенных ошибок, с которыми сталкивается программист при переносе приложений с Win32 на Win64 систему, является ошибка, связанная с использованием функции OnTimer. Функции OnTimer используется практически в каждом приложении и высока ве…

Andrey Karpov

Одной из самых распространенных ошибок, с которыми сталкивается программист при переносе приложений с Win32 на Win64 систему, является ошибка, связанная с использованием функции OnTimer. Функции OnTimer используется практически в каждом приложении и высока вероятность, что вы получите несколько ошибок компиляции. Ранее (в Visual Studio 6) эта функция имела прототип «OnTimer(UINT nIDEvent)» и скорее всего так же представлена в пользовательских классах. Сейчас эта функция имеет прототип «OnTimer(UINT_PTR nIDEvent)», что приводит к ошибке компиляции для 64-битной системы.

Рассмотрим стандартный пример:

class CPortScanDlg : public CDialog
{
  ...
  afx_msg void OnTimer(UINT nIDEvent);
  ...
};
BEGIN_MESSAGE_MAP(CPortScanDlg, CDialog)
...
  ON_WM_TIMER()
END_MESSAGE_MAP()

Для данного кода на этапе компиляции будет выдана следующая ошибка:

1>.SrcPortscandlg.cpp(136) : error C2440: 'static_cast' :
cannot convert from 'void (__cdecl CPortScanDlg::* )(UINT)' to
'void (__cdecl CWnd::* )(UINT_PTR)'
1> Cast from base to derived requires dynamic_cast or static_cast

Дело в том, что в макросе ON_WM_TIMER происходит явное приведение типа функции:

#define ON_WM_TIMER() 
{ WM_TIMER, 0, 0, 0, AfxSig_vw, 
  (AFX_PMSG)(AFX_PMSGW) 
  (static_cast< void (AFX_MSG_CALL CWnd::*)(UINT_PTR) > 
    ( &ThisClass :: OnTimer)) },

Приведение успешно выполняется при сборке 32-битной версии, так как типы UINT и UINT_PTR совпадают. В 64-битном режиме это различные типы и приведение типа функции невозможно, отчего и возникает на первый взгляд не очень понятная ошибка компиляции.

Исправить данную ошибку достаточно просто. Необходимо изменить объявление функции OnTimer в пользовательских классах. Пример исправленного кода:

class CPortScanDlg : public CDialog
{
  ...
  afx_msg void OnTimer(UINT_PTR nIDEvent); //Fixed
  ...
};

Иногда в программах функция OnTimer используется неоднократно.

Можно порекомендовать сразу поискать строчку «OnTimer(UINT » и заменить ее на «OnTimer(UINT_PTR «. Также можно воспользоваться множественной заменой, как показано на рисунке 1.

k0011_error_C2440_OnTimer_ru/image1.png

Рисунок 1 — Использование функции «Find and Replace» для исправления объявления функций OnTimer

Не забудьте только, что в обоих случаях в конце строк должен стоять пробел. Этот пробел, к сожалению, не виден на рисунке. Если пробелов не будет, то у вас может получиться «OnTimer(UINT_UINT_PTR nIDEvent)».

Присылаем лучшие статьи раз в месяц

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <math.h>
#include <windows.h>
#include <stdio.h>
 
void inputData (int *M11,int *M12,int *M13,int *M21,int *M22,int *M23,int *M31,int *M32,int *M33)
{
    printf("введите оценки первого студента через пробелn");    
    scanf("%d%d%d",&M11,&M12,&M13);
    printf("введите оценки второго студента через пробелn");
    scanf("%d%d%d",&M21,&M22,&M23);
    printf("введите оценки третьего студента через пробелn");
    scanf("%d%d%d",&M31,&M32,&M33);
}
void calcuateScholarship(float *S1,float *S2, float *S3)
{   int M11,M12,M13,M21,M22,M23,M31,M32,M33;
    if (M11==2 || M12==2 || M13==2)
        S1=0;
    else
    { if (M11==3 || M12==3 || M13==3)
    S1=(M11*250)+(M12*250)+(M13*250);
      if (M11==5 && M12==5 && M13==5)
          S1=(M11*250)+(M12*250)+(M13*250)+(((M11*250)+(M12*250)+(M13*250))*0.5);
      else
      S1=(M11*250)+(M12*250)+(M13*250)+(((M11*250)+(M12*250)+(M13*250))*0.25);}
 
if (M21==2 || M22==2 || M23==2)
        S2=0;
    else
    { if (M21==3 || M22==3 || M23==3)
    S2=(M21*250)+(M22*250)+(M23*250);
      if (M21==5 && M22==5 && M23==5)
      S2=(M21*250)+(M22*250)+(M23*250)+(((M21*250)+(M22*250)+(M23*250))*0.5);
      else
      S2=(M21*250)+(M22*250)+(M23*250)+(((M21*250)+(M22*250)+(M23*250))*0.25);}
if (M31==2 || M32==2 || M33==2)
        S3=0;
    else
    { if (M31==3 || M32==3 || M33==3)
    S3=(M31*250)+(M32*250)+(M33*250);
      if (M31==5 && M32==5 && M33==5)
          S3=(M31*250)+(M32*250)+(M33*250)+(((M31*250)+(M32*250)+(M33*250))*0.5);
      else
          S3=(M31*250)+(M32*250)+(M33*250)+(((M31*250)+(M32*250)+(M33*250))*0.25);}
}
 
int main()
{ 
  SetConsoleOutputCP(1251);
  int M11,M12,M13,M21,M22,M23,M31,M32,M33;
  float S1,S2,S3;
 inputData(&M11,&M12,&M13,&M21,&M22,&M23,&M31,&M32,&M33);
 calcuateScholarship(&S1,&S2,&S3);
 printf("S1=n%2.0f",S1);
 printf("S2=n%2.0f",S2);
 printf("S3=n%2.0f",S3);
 getchar();getchar();
}

Столкнулся с ошибкой при выделении памяти под структуру в Си. Вот строчка, на которую указывает ошибка компиляции:

RGBTRIPLE* StringPixels = malloc((abs(biCopy.biWidth) * sizeof(RGBTRIPLE)));

RGBTRIPLE это структура для пикселей:

typedef struct
{
    BYTE rgbtBlue;
    BYTE rgbtGreen;
    BYTE rgbtRed;
} RGBTRIPLE;

Если кому не понятно, могу кинуть полный код. Сам код пробую скомпилировать на VS 2012.

αλεχολυτ's user avatar

αλεχολυτ

28.2k10 золотых знаков52 серебряных знака114 бронзовых знаков

задан 31 июл 2016 в 17:36

Max_Advanced's user avatar

Max_AdvancedMax_Advanced

3111 золотой знак3 серебряных знака12 бронзовых знаков

malloc возвращает указатель типа void * для последующего использования его необходимо явно привести в нужный тип, например так:

RGBTRIPLE* StringPixels = (RGBTRIPLE*) malloc((abs(biCopy.biWidth) * sizeof(RGBTRIPLE)));

ответ дан 31 июл 2016 в 17:37

pavel's user avatar

1

Ваша проблема в том, что Вы компилируете сишный код компилятором c++. В c допускается неявное преобразование void* (который возвращает malloc) в T*, а вот в c++ это уже запрещено.

Поэтому, если код именно сишный, нужно и исходник компилировать как сишный. Для Visual Studio для этого обычно достаточно изменить расширение файла на .c.

Если же требуется обеспечить сборку в режиме c++, то требуется явное приведение типов, о котором уже сказано в другом ответе.

ответ дан 31 июл 2016 в 17:52

αλεχολυτ's user avatar

αλεχολυταλεχολυτ

28.2k10 золотых знаков52 серебряных знака114 бронзовых знаков

Ambiguous user-defined-conversion

Ambiguous is the keyword.

D<int, int> test3;
int t3 = test3;

Here the compiler doesn’t know wether to use const int &D<int, char>::operator const int &() or int &D<int, int>::operator int &().

The problem is that t3 is int and not int& or const int&.
If you actually work with references everything works fine (or at least as expected):

D<int, int> test3;
int& t31 = test3; //OK
const int& t32 = test3; //OK

D<int, char> test2;
int& t21 = test2; //Doesn't work
const int& t22 = test2; //OK

The problem is for the compiler to decide wether to use the const version of the base class or the non-const version of the inheriting class.

I would recommend you overload the const version of the operator in the inheriting class, so that the compiler can choose which one to use from this class only:

#include <iostream>

template <typename TYPE, typename SELECTOR = int> struct D {
    TYPE x;
    D() : x(2) {}
    D(TYPE X) : x(X) {}

    operator const TYPE&() const { return x; }
};
template <typename TYPE> struct D<TYPE, int> : public D<TYPE, char> {
    D() : D<TYPE, char>(3) {}

    operator const TYPE&() const { return D<TYPE, char>::x; }
    operator TYPE&() { return D<TYPE, char>::x; }
};

int main() {

    D<int, int> test3;
    int t3 = test3; //OK
    int& t31 = test3; //OK
    const int& t32 = test3; //OK

    D<int, char> test2;
    int t2 = test2; //OK
    //int& t21 = test2; //Doesn't work
    const int& t22 = test2; //OK

    std::cout << +t3 << " " << +t2 << "n";  // Expected output "3 2" (which we get from clang)
    return 0;
}

Other ways to address this problem:

You can now manually cast to int&

D<int, int> test3;
int t3 = (int&)test3;

or manually cast to const int&

D<int, int> test3;
int t3 = (const int&)test3;

or explicitly call the functions

D<int, int> test3;
int t3 = test3.operator int &();

or

D<int, int> test3;
int t3 = test3.operator const int &();

or you could make both function const

template <typename TYPE> struct D<TYPE, int> : public D<TYPE, char> {
    D() : D<TYPE, char>(3) {}
    operator const TYPE&() const { return D<TYPE, char>::x; }
};

Or you could just remove the redifinition of the function (As TYPE doesn’t change).

template <typename TYPE, typename SELECTOR = int> struct D {
    TYPE x;
    D() : x(2) {}
    D(TYPE X) : x(X) {}

    operator const TYPE&() const { return x; }
};

template <typename TYPE> struct D<TYPE, int> : public D<TYPE, char> {
    D() : D<TYPE, char>(3) {}
};

Yet I guess the latter 2 variants are not what you want because of the const.

Ambiguous user-defined-conversion

Ambiguous is the keyword.

D<int, int> test3;
int t3 = test3;

Here the compiler doesn’t know wether to use const int &D<int, char>::operator const int &() or int &D<int, int>::operator int &().

The problem is that t3 is int and not int& or const int&.
If you actually work with references everything works fine (or at least as expected):

D<int, int> test3;
int& t31 = test3; //OK
const int& t32 = test3; //OK

D<int, char> test2;
int& t21 = test2; //Doesn't work
const int& t22 = test2; //OK

The problem is for the compiler to decide wether to use the const version of the base class or the non-const version of the inheriting class.

I would recommend you overload the const version of the operator in the inheriting class, so that the compiler can choose which one to use from this class only:

#include <iostream>

template <typename TYPE, typename SELECTOR = int> struct D {
    TYPE x;
    D() : x(2) {}
    D(TYPE X) : x(X) {}

    operator const TYPE&() const { return x; }
};
template <typename TYPE> struct D<TYPE, int> : public D<TYPE, char> {
    D() : D<TYPE, char>(3) {}

    operator const TYPE&() const { return D<TYPE, char>::x; }
    operator TYPE&() { return D<TYPE, char>::x; }
};

int main() {

    D<int, int> test3;
    int t3 = test3; //OK
    int& t31 = test3; //OK
    const int& t32 = test3; //OK

    D<int, char> test2;
    int t2 = test2; //OK
    //int& t21 = test2; //Doesn't work
    const int& t22 = test2; //OK

    std::cout << +t3 << " " << +t2 << "n";  // Expected output "3 2" (which we get from clang)
    return 0;
}

Other ways to address this problem:

You can now manually cast to int&

D<int, int> test3;
int t3 = (int&)test3;

or manually cast to const int&

D<int, int> test3;
int t3 = (const int&)test3;

or explicitly call the functions

D<int, int> test3;
int t3 = test3.operator int &();

or

D<int, int> test3;
int t3 = test3.operator const int &();

or you could make both function const

template <typename TYPE> struct D<TYPE, int> : public D<TYPE, char> {
    D() : D<TYPE, char>(3) {}
    operator const TYPE&() const { return D<TYPE, char>::x; }
};

Or you could just remove the redifinition of the function (As TYPE doesn’t change).

template <typename TYPE, typename SELECTOR = int> struct D {
    TYPE x;
    D() : x(2) {}
    D(TYPE X) : x(X) {}

    operator const TYPE&() const { return x; }
};

template <typename TYPE> struct D<TYPE, int> : public D<TYPE, char> {
    D() : D<TYPE, char>(3) {}
};

Yet I guess the latter 2 variants are not what you want because of the const.

Я изучаю С++, и у меня возникают проблемы с некоторыми новинками. Я пытаюсь создать очень маленькое приложение, которое вводит пользователя и сохраняет его в массив char. Затем я разбираю этот массив и удаляю все скобки и dases и отображаю их. как показано ниже

(325) 858-7455
для изображения
3258587455

Но я получаю ошибки

 error C2440: '=' : cannot convert from 'const char [2]' to 'char'

Ниже приведен мой простой код, который можно легко загрузить в компилятор и запустить.

#include "stdafx.h"
#include<iostream>
#include<conio.h>

using namespace std;

/*
This is a template Project
*/
int main()
{
    char phoneNum[25];

    for(int i = 0; i < (sizeof(phoneNum) / sizeof(char)); i++)
    {
        phoneNum[i] = "i";
    }


    cout<< "Enter a phone Number" <<endl;
    cin>>phoneNum;

    if(phoneNum[0] != '(' || phoneNum[4] != ')' || phoneNum[8] != '-')
    {
        cout<<"error";
    }
    else
    {

        for(int i = 0; i < (sizeof(phoneNum) / sizeof(char));i++)
        {
            if(phoneNum[i] != '(' || phoneNum[i] != ')' || phoneNum[i] != '-')
            {
                cout<<phoneNum[i];
            }
        }
    }

    cin>>phoneNum;
    getchar();


    return 0;
}

Он не полностью закончен, поэтому, если у кого-нибудь есть указатели на лучший способ удалить строки символов из строки. это было бы прекрасно.

13 май 2010, в 17:14

Поделиться

Источник

5 ответов

Проблема здесь, я считаю:

phoneNum[i] = "i";

Вы хотите назначить один символ, поэтому вам нужно использовать одинарные кавычки для вашего литерала:

phoneNum[i] = 'i';

Там могут быть другие проблемы — я только попытался исправить то, что упоминалось в названии:)

Jon Skeet
13 май 2010, в 16:21

Поделиться

Здесь важно понять разницу между "i" и 'i'.

"i" — это строка, а строки хранятся в памяти как последовательность значений char, добавляя в конце строки нулевой символ (допустим, ноль). Поэтому, когда вы пишете "hello", вы сохраняете 'h' 'e' 'l' 'l' 'o' '(null)'. Точно так же, когда вы пишете "i", вы сохраняете 'i' '(null)', и это 'const char [2]' (массив из двух элементов char).

Когда вы берете массив char и используете оператор [], вы ссылаетесь на элемент 'char' в этом массиве. Поэтому, когда вы пишете phoneNum[i], вы получаете 'char'.

Вот почему вам нужно написать phoneNum[i] = 'i';

Diego Pereyra
13 май 2010, в 15:33

Поделиться

Я предлагаю использовать строки и потоки С++:

#include <string>
#include <iostream>
#include <cstdlib>

using std::string;
using std::cout;
using std::endl;
using std::cerr;
using std::cin;
using std::flush;

int main(void)
{
    string phone_number;
    cout << "Enter phone number: " << flush;
    getline(cin, phone_number);

    // Check first for valid characters
    const string valid_characters = "0123456789()- ";
    string::size_type position = phone_number.find_first_not_of(valid_characters);
    if (position != string::npos)
    {
        cerr << "Invalid phone number.n";
        return EXIT_FAILURE;
    }

    // Remove non-numeric characters
    const string chars_to_remove = " ()-";
    position = 0;
    while ((position = phone_number.find_first_of(chars_to_remove, position))
           != string::npos)
    {
        phone_number.erase(position, 1);
    }

    cout << "nPhone number only digits: " << phone_number << endl;
    return EXIT_SUCCESS;
}

В std::string есть много полезных методов для управления методами.

Рекомендации многих опытных разработчиков в Qaru для новичков учиться использовать строки С++ (std::string) перед использованием строк стиля C (char *).

Thomas Matthews
13 май 2010, в 19:08

Поделиться

phoneNum[i] = "i";

Вещь слева — это char; вещь справа — это строка, массив из char. Вы хотите 'i' справа.

AakashM
13 май 2010, в 15:34

Поделиться

Зачем вам нужна эта проверка? Что делать, если они хотели ввести неамериканский номер телефона, отформатированный так, как вы предлагали [значение с помощью парсеров и тире, но не ограничиваясь (3) 3-4]

if(phoneNum[0] != '(' || phoneNum[4] != ')' || phoneNum[8] != '-')
{
    cout<<"error";
}
else

Я бы удалил этот блок.

jcolebrand
13 май 2010, в 16:22

Поделиться

Ещё вопросы

  • 0Цифровой сплайс формат на сетке
  • 1минута даты JavaScript с ведущим нулем
  • 1Выделите строку ListView на основе идентификатора
  • 0Перенаправить на другой угол обзора
  • 0Как заставить фильтр искать информацию только в одном столбце с помощью jQuery?
  • 1Кажется, instanceof не работает — что не так с моим кодом?
  • 1Android-виджет с изменяющимся текстом
  • 0Zend Framework 2 включает
  • 1Как определить поддержку браузера http2 или нет в среде браузера по javascript?
  • 0Управление HTML одним нажатием кнопки (Meteor + Angular)
  • 0Выборочное управление запуском угловых часов при сравнении объекта
  • 0передача данных td на скрытый ввод и последующее размещение с помощью PHP
  • 0проблема, связанная с методом POST и GET в HTML
  • 1Детализированный объект Spring-Data на дочернем объекте
  • 1java — slick2d — statebasedgame error — в текущем потоке не найден контекст OpenGL
  • 0Как я могу проверить, есть ли Angular.js, загруженный на страницу? [Дубликат]
  • 0Как отобразить URL изображения с подстраниц сайта, используя php код
  • 0Присоединение объекта в месте щелчка с абсолютной позицией
  • 0php получает информацию о фейсбуке, используя имя пользователя и пароль
  • 1Странное исключение из PreferencesActivity
  • 1Android-будильник
  • 0defaultValue не работает в коде JavaScript
  • 1Получение значения HiddenField и переход в var в JS
  • 0сумма значений в полях ввода с использованием jquery не работает
  • 0Добавление слушателей событий onclick и элементов с использованием javascript
  • 0sort3 не был объявлен в этой области
  • 1Добавление полосы прокрутки в пользовательскую ViewGroup?
  • 1d3.js интерполяция не работает
  • 0Как заставить сайт PHP жить на экземпляре Amazon EC2?
  • 0Серый фон
  • 1Javascript поиск ключа объекта в наборе
  • 0Событие щелчка jQuery не запускается для привязки, если оно содержится в ячейке slickgrid
  • 1Это значение по сравнению со значением?
  • 1Доступ к службе WCF из PCL
  • 1Как .NET AppDomains поддерживает работу размещенного процесса?
  • 0Как изменить регулярное выражение на http / https?
  • 0MySQL считает разные значения в одной таблице
  • 0Среднее различие между 2 числами, расположенными в 2 разных таблицах
  • 1Как добавить элементы из строки, добавленной из консоли, в список в Java
  • 0Как я могу преобразовать дату и время: 1518427800 в чч: мм: сс дд / мм / гггг в node.js?
  • 1Панды — сопоставить несколько строк из другого DF в несколько столбцов
  • 1Ошибка веб-приложения NetBeans 404 включает JS
  • 1Скачать несколько файлов sharpSSH
  • 0Раскройте PHP через HTTPRequest
  • 1Struts 2 FilterDispatcher устарел
  • 0Обновление записей на основе даты на MySQL с помощью объединений
  • 1Нужно разделить запрос xml на разные xmls
  • 1поиск записи Hbase с использованием API Java?
  • 0Предотвратить угловой от выполнения цикла дайджеста
  • 0Когда бы вы использовали mysqli с ssl (ssl_set)

Сообщество Overcoder

Это отличается от аналогичных вопросов, потому что я устанавливаю значение указателя на адрес, вместо того, чтобы пытаться назначить несовместимый тип … Я думаю.

template <class Type>
class ArrayStack
{
private:
int sz; // stack size
int asz; // array size (implementation)
Type* start; // address of first element
Type arr[]; // Might need to intialize each element to 0!?
public:
ArrayStack() { sz = 0; arr[0] = 0; asz = 0; start = &arr; }
/* other code... */
};

-1

Решение

start = arr; должен сделать свое дело.

  • Вы можете назначить массив указателю, и указатель будет установлен на начало массива.

Кроме того, спецификация пустого массива:

Type arr[];

Не уверен, что это значит. Вероятно, так же, как:

Type arr[0];

Более нормально:

Type arr[asz];

Конечно, размер массива должен быть постоянным.

0

Другие решения

Предложить использование std::vector<Type> arr вместо Type arr[],

template <class Type>
class ArrayStack
{
private:
int sz; // stack size
int asz; // array size (implementation)

// Type* start; // address of first element
// Don't need this at all.
// You can use &arr[0] any time you need a pointer to the
// first element.
std::vector<Type> arr;
public:

// Simplified constructor.
ArrayStack() : sz(0), asz(0), arr(1, 0) {}

/* other code... */
};

0

Понравилась статья? Поделить с друзьями:
  • C2402 ошибка kia sportage
  • C2402 ошибка kia rio
  • C2402 hyundai accent ошибка
  • C2400 ошибка kia
  • C2395 ошибка kia mohave