2010-01-10 3 views
1
int utstrlen(char* src){ 
    int length=0 ; 
    if(isOurs(src) ==1){ 
     length = src - 2 * sizeof(int); 
    } 
    return length; 
} 

'C4047'이라는 경고 메시지가 나타납니다. '=': 'int'는 'char *'오류와의 간접 레벨이 다릅니다. 줄 length = src - 2 * sizeof(int);에서 누군가 그 문제가 무엇인지 설명 할 수 있습니까? 고맙습니다!경고 C4047 : '=': 'char *'의 간접 레벨이 '

+0

수량 또는 길이가 아닌 해당 행의 포인터를 계산 중입니다. 의사 코드 또는 길이에 대한 설명을 제공 할 수 있습니까? –

답변

3

기반 귀하의 previous question에, 당신은 원하는 패딩을 가정하지 않지만

length = *((int *)(src - 2 * sizeof(int))); 

입니다. 더 좋은 방법은 offsetof()을 사용하는 것입니다 :

String *beg = (String *)(src - offsetof(struct String, ptr)); 
length = beg->length; 

나는 당신이 당신의 이전 질문에서 구조체를 사용하는 가정입니다.

0

srcchar *이고; 길이는 int입니다. 컴파일러는, 따라서, 유사한이 줄을 치료한다 :

length = (int) (src - 2 * sizeof(int)); 

내가 경고에 대해 당신에게 혼란 모르겠어요, 그리고 나는 또한 코드가 시도 된 사항에 대한 혼란 스러워요.

void test(void) { 
    char *foo = "hello\n"; 

    printf("%s\n", foo); 
    printf("%d\n", (int) foo); 
    printf("%s\n", foo+1); 
    printf("%d\n", ((int) foo) + 1); 
} 

는 해당 연산이 다른보다 포인터 중 하나 개 사용에 더 의미가 알게 될 것이다 : 나의 제안하고, 다음 테스트 코드를 시도하고 출력을 확인하는 것입니다.

0

src - 2 * sizeof(int)은 포인터 연산입니다.이 표현식의 결과는 또 다른 char* 포인터입니다. (int)에 char*을 할당하려 했으므로 오류가 발생합니다. 이 함수가 무엇을해야할지 모르지만 실제로 원한다면 int : length = (int)(src - 2 * sizeof(int)) 값을 전송할 수 있습니다. 그러나 다시, 나는 당신의 기능에서 그 사용법을 보지 못합니다.

0

확실히.

src은 포인터입니다. 2 * sizeof(int)은 정수 값입니다.

  1. 은 (아마도, 정수 통합 유형으로, 그 결과는 자신의 주소의 차이 인 size_tptrdiff_t)를 서로 두 포인터를 뺄 실제로 법적 있지만, 또한

  2. 포인터에서 정수를 뺀 결과 (결과는 해당 포인터보다 조금 앞선 위치에 대한 포인터 임)

(2)의 결과를 정수 변수 (length)에 할당하려고 시도하는 것은 적합하지 않습니다.

+1

(1)의 결과는 여전히 포인터 너비 유형이며 int가 아닙니다. – wj32

+0

맞습니다. 정수형이지만'int' 형은 아닙니다. 그러나 컴파일러에 따라 int로 inter-assignable 일 수 있습니다. –

+0

엄밀히 말하면 배열의 멤버를 가리키는 포인터 두 개만 빼기 만하면 ptrdiff_t 유형입니다. –

1

나는이 같은 문자열 구조체가 의심 :

struct string { 
    int length; 
    int somethingelse; /* thanks alok */ 
    char *str; 
} 

을이 기능은 STR에 대한 포인터를 제공 할 때 길이 필드에 액세스하려고? 나 맞아? 이것이 isOur가 (이전의 문자열이 아닌지) 확인하는 것입니다.

length = (*((int*)(src - 2))) * sizeof(int);

int utstrlen(char* src){ 
    int length=0 ; 
    if(isOurs(src) ==1){ 
      length = *((int*)(src - (2 * sizeof(int)))); /* from str moveback 2 ints worth*/ 
    } 
    else { 
     //return strlen(src) ? 
    } 
    return length; 
} 

을하지만 이상적으로 당신은 그렇게 할 wouldn'd : 어떤 경우에, 당신이 원하는. 휴대용 또는 유지 보수가 불가능합니다. 컴파일러에서 모르는 패딩을 삽입하면 어떻게됩니까?C99 표준은 0 크기의 배열과 이전 필드 사이에 패딩을 넣지 않겠지 만, 다른 필드와는 화를 낼 수 없습니다 (예 : 유형이 혼합 된 경우).

나중에 누군가가 따라 와서 더 많은 데이터를 구조에 삽입하면 어떻게됩니까? 당연히, 'struct hack'은 마지막에 그것을 가짐으로써 작동하므로, 필드 str 앞에 붙여야합니다. 이상적으로 표준 매크로 인 offsetof()를 사용해야합니다. 알록 더 나은 여기에 솔루션 Ugly Macro Interpretation (just 1 line)

편집 (그것이 그 새 마지막 단락을 입력 데려 2 분 같다, 알록의을 offsetof() 답이 하나 이상 받아 들여졌다를) 제공)

+0

그 중 하나가 올바르게 보이지 않습니다. '길이 = * ((int *) src - 2);'가능성이 더 높습니다. – caf

+0

아 예, 캐스트하는 것을 잊었습니다 :) – Pod

+0

'length = ...'행에서 무엇을 하려는지 확실하지 않습니다. 대부분의 경우 구조체는'char * '앞에 두 개의'int'멤버가 있고'2 * sizeof (int) '를 빼면 구조체의 시작 부분에 주소가 부여됩니다 (패딩이 없다고 가정). 더 좋은 방법은'offsetof' 매크로를 사용하는 것입니다. –

관련 문제